好的!以下是关于 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) | 获取当前场景的状态(active 、inactive 或 background )。 | |
环境注入 | @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)
}
}
}
}
注意事项 #
- 多窗口支持:在 iPadOS 和 macOS 上,
WindowGroup
支持多窗口,但在 iOS 上默认只支持单窗口。 - 状态管理:推荐使用
@StateObject
或@ObservedObject
管理跨场景的状态。 - 生命周期监听:通过
@Environment(\.scenePhase)
可以精确控制场景的激活和去激活逻辑。 - 性能优化:避免在
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 | 设置此场景创建的菜单栏额外样式的样式。 |