SwiftUI 与传统的 UIKit 思路不同,是一种声明式 UI 结构,这种结构的特点便是摒弃了传统开发的代码按生命周期进行的流程概念,直接经过声明所出现的内容来与用户进行交互。

App

protocol App

App 代表了使用程序的抽象,需要在它的 body 特点中声明使用所能够出现的内容:

@main
struct MyApp: App { 
    var body: some Scene { 
        WindowGroup { 
            Text("Hello, world!") 
        } 
    } 
}

在你的自定义实现结构体声明之上增加 @main,用来符号这是使用程序的仅有主进口。同时,这也意味着你的使用程序只能有这一个主进口。

Scene

App 的 body 特点中,能够组合一个或多个 Scene 的实现,每一个 Scene 实现包含视图结构的根视图,代表用户界面中的内容,也可能是一部分(多窗口),它的生命周期由体系管理。

SwiftUI 供给了一些 Scene 的实现来表明场景的场景,包含显现设置或是文档。 你也能够自定义创立 Scene,但其实便是组合一些体系供给的 Scene:

struct MyScene: Scene {
    var body: some Scene {
        WindowGroup {
            MyRootView()
        }
    }
}

Scene 有一些常见实现:

  • WindowGroup
  • Settings
  • Window
  • ImmersiveSpace
  • DocumentGroup

SwiftUI 是跨渠道结构,所以根据不同的渠道支撑的 Scene 也有所不同。例如,visionOS 不支撑 Window,而 ImmersiveSpace 是 visionOS 独有的。

App 的 body 中能够包容一个或多个 Scene:

@main
struct Mail: App {
    var body: some Scene {
        WindowGroup {
            MailViewer()
        }
        Settings {
            SettingsView() 
        }
    }
}

使用启动,会默认打开第一个 Scene 所出现的内容。针对不同的渠道,可能需要修正 plist 来支撑多场景。例如,在 visionOS 渠道或 iPadOS,需要增加 Enable Mutiple Windows 为 YES。

SwiftUI App Structure

Scene 本质上便是出现 View 结构的容器,体系会决定他们的显现行为,例如,在 iPadOS 或 macOS 支撑多窗口,用户就能够创立或是删去一些窗口;而在 iOS 渠道(or 其他)当使用处于活泼状况,视图内容将会占满整个屏幕。

Scene 的生命周期

能够经过环境值 scenePhase 来从 Scene 或 View 中读取当前 Scene 是否处于活泼状况:

struct MyScene: Scene {
    @Environment(\.scenePhase) private var scenePhase
    // ...
}

scenePhase 是枚举类型 ScenePhase,包含:

  • background:处于后台,不行交互;
  • inactive:处于前台,不行交互;
  • active:处于前台,能够交互。

Scene 供给了一些办法,能够对 Scene 进行装备,例如能够运用 onChange(of:perform) 来监听某个值的改变,然后触发一些操作,下面是一个当使用进入后台后清除缓存的操作:

struct MyScene: Scene {
    @Environment(\.scenePhase) private var scenePhase
    @StateObject private var cache = DataCache()
    var body: some Scene {
        WindowGroup {
            MyRootView()
        }
        .onChange(of: scenePhase) { newScenePhase in
            if newScenePhase == .background {
                cache.empty()
            }
        }
    }
}

Scene 之间的通讯

多个 Scene 能够经过在 App 中声明一些状况来进行通讯。例如,运用 @StateObject 来初始化一个数据类,然后将数据类作为 ObservedObject 或经过环境作为 EnvironmentObject 供给给 Scene:

@main
struct Mail: App {
    @StateObject private var model = MailModel()
    var body: some Scene {
        WindowGroup {
            MailViewer()
                .environmentObject(model) // Passed through the environment.
        }
        Settings {
            SettingsView(model: model) // Passed as an observed object.
        }
    }
}

总结

SwiftUI App 以 App 协议的实现为使用主进口,其 body 特点中能够装备多个 Scene,App 启动时默认打开第一个 Scene。 Scene 代表用户界面的容器,用来承载视图结构,其内容是视图结构的根视图。Scene 具有生命周期,包含三种:

  1. backgroud
  2. inactive
  3. active 能够经过环境特点 scenePhase 来查询。 Scene 直接能够经过在 App 中定义同享的数据结构来同享数据。能够经过一些办法或经过参数的形式传递到不同的 Scene。