SwiftUI — Scene

好的!以下是关于 SwiftUI Scene 体系结构的详细介绍,并按照清晰的分类和表格形式整理。


SwiftUI Scene 体系结构概述 #

在 SwiftUI 中,Scene 是应用的核心组成部分之一,用于定义应用的不同界面或功能模块。每个 Scene 都是一个独立的视图层级,可以被系统管理和展示。通过 Scene,开发者可以灵活地管理应用的窗口、生命周期以及多窗口支持(如 macOS 和 iPadOS 的多窗口特性)。


SwiftUI Scene 的主要组成部分 #

1. App 协议与 Scene 定义 #

  • 在 SwiftUI 中,应用的入口是符合 App 协议的结构体。
  • App 协议要求实现 body 属性,该属性返回一个或多个 Scene
  • 常见的 Scene 类型包括:
    • WindowGroup:用于定义应用的主要窗口组。
    • Settings:用于定义应用的设置界面。
    • DocumentGroup:用于支持文档编辑的应用场景。

2. Scene 的生命周期 #

SwiftUI 提供了对 Scene 生命周期的支持,允许开发者在场景激活、去激活或进入后台时执行特定逻辑。


SwiftUI Scene 的主要方法与功能分类 #

以下是 SwiftUI Scene 的主要方法和功能分类:

类别方法/属性名称描述
App 入口定义@main标记应用的入口点。
var body: some Scene定义应用的主场景,返回一个或多个 Scene
窗口管理WindowGroup定义应用的主要窗口组,包含多个可复用的视图。
DocumentGroup用于支持文档编辑的应用场景,提供文件打开和保存的功能。
Settings定义应用的设置界面,通常与系统设置集成。
生命周期管理.onChange(of:perform:)监听某个状态的变化,例如 scenePhase 的变化。
@Environment(\.scenePhase)获取当前场景的状态(activeinactivebackground)。
环境注入@EnvironmentObject注入共享的状态对象到视图层级中。
.environmentObject(_:)将状态对象传递给子视图。
多窗口支持WindowGroup(id:content:)支持多窗口应用,允许为不同窗口指定唯一标识符。
动态内容更新.onAppear当视图出现在屏幕上时调用。
.onDisappear当视图从屏幕上消失时调用。

SwiftUI Scene 的继承关系与实现 #

1. App 协议的实现 #

每个 SwiftUI 应用都需要一个符合 App 协议的结构体作为入口点。以下是一个简单的示例:

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

2. Scene 的嵌套与组合 #

可以通过组合多个 Scene 来定义复杂的应用结构。例如:

@main
struct MyApp: App {
    var body: some Scene {
        // 主窗口组
        WindowGroup {
            ContentView()
        }
        // 设置界面
        Settings {
            SettingsView()
        }
    }
}

3. 生命周期管理 #

使用 @Environment(\.scenePhase) 可以监听场景的状态变化:

struct ContentView: View {
    @Environment(\.scenePhase) private var scenePhase

    var body: some View {
        Text("Hello, World!")
            .onChange(of: scenePhase) { newPhase in
                switch newPhase {
                case .active:
                    print("Scene is active")
                case .inactive:
                    print("Scene is inactive")
                case .background:
                    print("Scene is in background")
                @unknown default:
                    print("Unknown scene phase")
                }
            }
    }
}

使用场景与示例代码 #

示例 1:定义一个简单的窗口组 #

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            NavigationView {
                List {
                    Text("Item 1")
                    Text("Item 2")
                }
                .navigationTitle("My List")
            }
        }
    }
}

示例 2:支持多窗口 #

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup("Main") {
            ContentView()
        }
        WindowGroup("Secondary", id: "secondary") {
            SecondaryView()
        }
    }
}

示例 3:管理文档编辑 #

@main
struct MyApp: App {
    var body: some Scene {
        DocumentGroup(newDocument: MyDocument()) { file in
            ContentView(document: file.$document)
        }
    }
}

示例 4:设置界面 #

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        Settings {
            Form {
                Toggle("Enable Feature", isOn: $featureEnabled)
            }
        }
    }
}

注意事项 #

  1. 多窗口支持:在 iPadOS 和 macOS 上,WindowGroup 支持多窗口,但在 iOS 上默认只支持单窗口。
  2. 状态管理:推荐使用 @StateObject@ObservedObject 管理跨场景的状态。
  3. 生命周期监听:通过 @Environment(\.scenePhase) 可以精确控制场景的激活和去激活逻辑。
  4. 性能优化:避免在 Scene 初始化时执行耗时操作,确保应用启动快速。

SwiftUI Scene 方法与功能分类 #

类别方法/属性名称描述
创建场景var body: Self.Body定义场景的内容和行为。
associatedtype Body : Scene定义场景主体的类型。
监听变化func onChange(of:initial:_:)添加一个动作以在给定值发生变化时执行。
func handlesExternalEvents(matching: Set<String>) -> some Scene指定 SwiftUI 为修改后的场景打开新实例的外部事件。
创建后台任务func backgroundTask<D, R>(BackgroundTask<D, R>, action: (D) async -> R)当系统提供后台任务时运行指定的动作。
管理应用存储func defaultAppStorage(UserDefaults) -> some Scene设置场景及其视图内容中包含的 AppStorage 默认存储。
设置命令func commands<Content>(content: () -> Content) -> some Scene为场景添加命令。
func commandsRemoved() -> some Scene移除由修改后的场景定义的所有命令。
func commandsReplaced<Content>(content: () -> Content) -> some Scene替换由修改后的场景定义的所有命令。
func keyboardShortcut(KeyboardShortcut?) -> some Scene定义用于打开新场景窗口的键盘快捷键。
func keyboardShortcut(KeyEquivalent, modifiers: EventModifiers, localization: KeyboardShortcut.Localization) -> some Scene定义用于打开新场景窗口的键盘快捷键。
调整大小与定位func defaultPosition(UnitPoint) -> some Scene设置窗口的默认位置。
func defaultSize(_:)设置窗口的默认大小。
func defaultSize(width: CGFloat, height: CGFloat) -> some Scene设置窗口的默认宽度和高度。
func defaultSize(width: CGFloat, height: CGFloat, depth: CGFloat) -> some Scene设置体积窗口的默认大小。
func defaultSize(Size3D, in: UnitLength) -> some Scene设置体积窗口的默认大小。
func defaultSize(width: CGFloat, height: CGFloat, depth: CGFloat, in: UnitLength) -> some Scene设置体积窗口的默认大小。
func defaultWindowPlacement((WindowLayoutRoot, WindowPlacementContext) -> WindowPlacement) -> some Scene定义确定窗口默认放置的函数。
func windowResizability(WindowResizability) -> some Scene设置窗口的可调整大小类型。
func windowIdealSize(WindowIdealSize) -> some Scene指定缩放时窗口应如何确定其大小。
func windowIdealPlacement((WindowLayoutRoot, WindowPlacementContext) -> WindowPlacement) -> some Scene提供一个函数,用于确定场景窗口缩放时使用的放置位置。
func windowManagerRole(WindowManagerRole) -> some Scene配置从自身派生的窗口的角色。
交互体积func volumeWorldAlignment(WorldAlignmentBehavior) -> some Scene指定体积在世界中移动时的对齐方式。
func defaultWorldScaling(WorldScalingBehavior) -> some Scene指定窗口的世界缩放行为。
配置场景可见性func defaultLaunchBehavior(SceneLaunchBehavior) -> some Scene设置此场景的默认启动行为。
func restorationBehavior(SceneRestorationBehavior) -> some Scene设置此场景的恢复行为。
func persistentSystemOverlays(Visibility) -> some Scene设置非瞬态系统视图覆盖应用的首选可见性。
样式化场景func immersionStyle(selection: Binding<any ImmersionStyle>, in: any ImmersionStyle...) -> some Scene设置沉浸式空间的样式。
func upperLimbVisibility(Visibility) -> some Scene设置呈现沉浸式空间时用户的上肢首选可见性。
func windowStyle<S>(S) -> some Scene设置由该场景创建的窗口样式。
func windowLevel(WindowLevel) -> some Scene设置场景的窗口级别。
func windowToolbarStyle<S>(S) -> some Scene设置此场景内定义的工具栏样式。
func windowToolbarLabelStyle(Binding<ToolbarLabelStyle>) -> some Scene设置工具栏项的标签样式并启用用户自定义。
func windowToolbarLabelStyle(fixed: ToolbarLabelStyle) -> some Scene设置工具栏项的标签样式。
配置数据模型func modelContext(ModelContext) -> some Scene在场景环境中设置模型上下文。
func modelContainer(ModelContainer) -> some Scene在场景环境中设置模型容器和关联的模型上下文。
func modelContainer(for:inMemory:isAutosaveEnabled:isUndoEnabled:onSetup:)为提供的模型类型设置模型容器,并在必要时创建新容器,同时在场景环境中设置模型上下文。
管理环境func environment<T>(T?) -> some Scene将可观察对象放入场景环境中。
func environment<V>(WritableKeyPath<EnvironmentValues, V>, V) -> some Scene将指定键路径的环境值设置为给定值。
func environmentObject<T>(T) -> some Scene向视图子层次结构提供 ObservableObject
func transformEnvironment<V>(WritableKeyPath<EnvironmentValues, V>, transform: (inout V) -> Void) -> some Scene使用给定函数转换指定键路径的环境值。
交互对话框func dialogIcon(Image?) -> some Scene配置警报使用的图标。
func dialogSeverity(DialogSeverity) -> some Scene设置警报的严重性。
func dialogSuppressionToggle(isSuppressed: Binding<Bool>) -> some Scene启用带有自定义抑制消息的用户警报抑制。
func dialogSuppressionToggle(_:isSuppressed:)启用带有自定义抑制消息的用户警报抑制。
支持拖拽行为func windowBackgroundDragBehavior(WindowInteractionBehavior) -> some Scene配置通过背景拖动窗口的行为。
已弃用符号func onChange<V>(of: V, perform: (V) -> Void) -> some Scene(已弃用)添加一个动作以在给定值发生变化时执行。
实例方法func documentBrowserContextMenu(([URL]?) -> some View) -> some Scene为文档组启动场景添加接受选定文件列表作为参数的操作。
func immersiveContentBrightness(ImmersiveContentBrightness) -> some Scene设置沉浸式空间的内容亮度。
func menuBarExtraStyle<S>(S) -> some Scene设置此场景创建的菜单栏额外样式的样式。

本文共 2358 字,创建于 Feb 23, 2025
相关标签: Xcode, SwiftUI