我正在使用 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()
}
}
}
}
有办法解决这个问题吗?我了解什么是不透明类型以及编译器告诉我什么,但我不确定如何解决它并实现我想要的功能。
问题是,当你说你的函数的返回值是
some Scene
时,Swift 期望单一类型,正如你提到的。函数构建器通常可以解决这个问题,例如 ViewBuilder
、SceneBuilder
(您可能需要这里)和其他方法,方法是能够获取符合返回协议(此处场景)的多个项目并将它们转换为单个项目。
App
的 var body
,您会发现这是一个 @SceneBuilder
。 SceneBuilder
可以将多个Scene
作为闭包输入,它们将被转换为另一个Scene
。但是,@SceneBuilder
(与 @ViewBuilder
不同)无法处理 if-else 子句,如 SceneBuilder 的 buildOptional
方法中所述。
SceneBuilder 中的条件语句可以包含 if 语句,但不能包含 else 语句,并且条件只能执行编译器检查可用性 [...]。