SwiftUI构建App入口Scene列表的@SceneBuilder
SwiftUI构建App入口Scene列表的@SceneBuilder

SwiftUI构建App入口Scene列表的@SceneBuilder

@SceneBuilder 是 SwiftUI 中的一个属性包装器,用于构建 App 入口的 Scene 列表。通常会在 SwiftUI App 的入口(符合 App 协议的 struct)中看到它,用来声明多个 Scene(窗口、菜单栏、文档等)。

例如,在SwiftUI中的body背后就是由 @SceneBuilder 包装器支持的。

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

基本定义

@available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, visionOS 1.0, *)
@resultBuilder public struct SceneBuilder {
    // 实现了构建多个 Scene 的方法
}

@SceneBuilder 是一个 Result Builder(结果构建器),允许像写 DSL(领域特定语言)一样写多个 Scene。

代码示例

例如,在使用MenuBarExtra状态栏时,可以将MenuBarExtra使用 @SceneBuilder 封装成Scene:

@main
struct ImageSlimApp: App {
    
    @SceneBuilder
    var menuBarExtraScene: some Scene {
        if #available(macOS 13.0, *) {
            MenuBarExtra("我的图标", systemImage: "gearshape") {
                Button("执行操作") {
                    print("点击了菜单项")
                }
                Divider()
                Button("退出") {
                    NSApp.terminate(nil)
                }
            }
        }
    }
    
    var body: some Scene {
        menuBarExtraScene
        WindowGroup {
            ContentView()
        }
    }
}

在这个代码中 @SceneBuilder 是一个结果构建器(Result Builder),用于构建多个 Scene(即多个窗口或菜单栏等界面容器)。它的作用是在 menuBarExtraScene 中像写 DSL 一样用 if 条件语句、多个 Scene 并列声明等方式灵活构建内容。

@SceneBuilder
var menuBarExtraScene: some Scene {
    if #available(macOS 13.0, *) {
        MenuBarExtra("我的图标", systemImage: "gearshape") {
            Button("执行操作") {
                print("点击了菜单项")
            }
            Divider()
            Button("退出") {
                NSApp.terminate(nil)
            }
        }
    }
}

@SceneBuilder 是一个 SwiftUI 提供的构建器属性(Attribute),用于组装多个 Scene。

如果不用 @SceneBuilder,则无法直接在 var 中写 if 和多个 Scene 返回值的,编译器会报错。

报错信息:

Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type
// 函数声明了一个不透明的返回类型,但其主体中没有返回语句来推断底层类型

因此,@SceneBuilder 的作用就是让这种 DSL 式的写法合法并且有语义。

最后,在var body中的两个Scene:

一个是 macOS 13+ 的菜单栏图标(MenuBarExtra)。

一个是常规窗口 WindowGroup。

和其他 builder 的类相比

1、构建View:使用@ViewBuilder。

var body: some View { ... }

2、构建Scene:使用@SceneBuilder。

var body: some Scene { ... }

3、构建 Commands:使用@CommandsBuilder。

var commands: some Commands

4、构建 ToolbarContent:使用@ToolbarContentBuilder。

总结

@SceneBuilder 是 SwiftUI 用来构建多个 Scene(如窗口、菜单栏、设置窗口)的结果构建器,它能像写多段 View 一样,声明多个 Scene,常见于 App 协议中。

相关文章

macOS状态栏MenuBarExtra:https://fangjunyu.com/2025/06/29/macos%e7%8a%b6%e6%80%81%e6%a0%8fmenubarextra/

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注