SwiftUI

2023 年 9 月 10 日

SwiftUI App 的視窗:Scene

已複製到剪貼板


定義多組的 UI 來組成整個 App。

SwiftUI Scene 概覽

Scene 就像個容器,裝著裡面的 View,用來呈現 App 的畫面,並由系統來管理它的生命週期。

SwiftUI Scene
SwiftUI Scene

系統會根據不同的 Scene type、不同的 OS 用不同的方式來呈現 Scene,一個 Scene 可能會佔滿整個螢幕,可能是部分的螢幕,也可能是一個視窗。有些時候 App 有能力同時呈現多個畫面,像在 iPadOS、macOS、visionOS 上,使用者可以對同一個 App 開多個視窗(WindowGroup)。而內建的 Scene 有兩種:Windows 和 Documents。

App 由 Scene 組成

我們可以在 app 的 body 裡,用多個 Scene 來組出我們的 App,除了使用 SwiftUI 內建的 WindowGroup,我們也能透過遵從 Scene protocol 來實作客製的 Scene,如下:

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

Scene 的生命週期:ScenePhase

作為 app 最上層的 Scene,我們可以用 @Environment 從環境中拿到 scenePhase 變數,來監控這個 Scene 是不是在 active 的狀態、背景的狀態或其他。

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

我們可以使用 modifier 來設定 Scene,就像平常我們會對 View 做的那樣,如 Windows Scene Type 就能用 windowStyle(_:) 來設定樣式、用 commands(content:) 來新增工具列選單。而要判斷 Scene 的生命週期的話,就可以使用 onChange(of: perform:) modifier,當值發生變化時,就觸發執行某件事。

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 退到背景時,清空 Cache。

分享文章

已複製到剪貼板

主題文章

查看 SwiftUI

超級感謝

關於 XcodeProject

XcodeProject 創立於 2023,致力於協助開發者探索 Apple 的創新世界,學習在 iOS、iPadOS、macOS、tvOS、visionOS 與 watchOS 上開發 App,發現眾多技術與框架,讓開發者獲得更多能力。


Contacts

Ricky Chuang

XcodeProject

RickyChuang.xcodeproj@gmail.com

XcodeProject 聯絡

contact.xcodeproj@gmail.com

最新文章