在 SwiftUI 中有条件地渲染 MenuBarExtra

问题描述 投票:0回答:1

我正在使用 SwiftUI 编写一个 mac 应用程序,我的应用程序包含一个菜单栏项。我想根据某些全局设置显示两种“类型”的菜单栏项目之一(一种带有滴答计时器,一种是静态图像)。

但是,我遇到了一个问题,Swift 期望底层

Scene
类型相同,但事实并非如此,因为我使用了两种不同的初始值设定项:

@main
struct MyApp: App {
    var body: some Scene {
        self.menuBarExtra()
        ContentView()
    }

    // ERROR: Function declares an opaque return type 'some Scene', but the return statements in its body do not have matching underlying types
    private func menuBarExtra() -> some Scene {
        if $showTimerInMenuBar {
            return MenuBarExtra(content: {AppMenu()}, label: {Text(timeRemainingFormatted)})
        }
        else {
            return MenuBarExtra("App", systemImage: "someImage") {
                AppMenu()
            }
        }
    }
}

有办法解决这个问题吗?我了解什么是不透明类型以及编译器告诉我什么,但我不确定如何解决它并实现我想要的功能。

swift macos swiftui
1个回答
0
投票

问题是,当你说你的函数的返回值是

some Scene
时,Swift 期望单一类型,正如你提到的。函数构建器通常可以解决这个问题,例如
ViewBuilder
SceneBuilder
(您可能需要这里)和其他方法,方法是能够获取符合返回协议(此处场景)的多个项目并将它们转换为单个项目。

但是,遗憾的是,目前您想要的场景是不可能的。如果您查看

App
var body
,您会发现这是一个
@SceneBuilder
SceneBuilder
可以将多个
Scene
作为闭包输入,它们将被转换为另一个
Scene
。但是,
@SceneBuilder
(与
@ViewBuilder
不同)无法处理 if-else 子句,如 SceneBuilder 的
buildOptional
方法中所述。

SceneBuilder 中的条件语句可以包含 if 语句,但不能包含 else 语句,并且条件只能执行编译器检查可用性 [...]。

© www.soinside.com 2019 - 2024. All rights reserved.