WWDC22

2023 年 10 月 2 日

SwiftUI 中的五種 Scene

已複製到剪貼板


SwiftUI 有五種不同的 Scene,可以幫助我們在不同的平台上實現不同的功能。

Five Scenes in SwiftUI

SwiftUI App 的組成

一個 SwiftUI App 會由一個或多個 Scene 組成,而每個 Scene 又可以由 View 組成。

五種不同的 SwiftUI Scene

在 SwiftUI 有五種不同的 Scene,分別是:WindowGroup、DocumentGroup、Settings、Window、MenuBarExtra,這些 Scene 可以一起使用來增加 App 的功能。

iOS iPadOS macOS tvOS visionOS watchOS
WindowGroup
DocumentGroup
Settings
Window
MenuBarExtra

WindowGroup

WindowGroup 適用於所有的 Apple Platform,可用來實現透過資料驅動(data-driven)的視窗。

DocumentGroup

DocumentGroup 可用來實現以文件為主的的 App。

Settings

Settings 可用來實現 macOS App 的設定畫面。

Window

Window 可以用來實現 App 中單一且唯一的視窗畫面,不像 WindowGroup,Window 在顯示它的內容時,最多只會有一個視窗,如果此 Window 已存在,系統會將 Window 移至最前,而非新增一個。這樣的特性在用來呈現整個 App 的狀態時非常有用,或是像遊戲也不會希望有兩個一樣的視窗存在。

MenuBarExtra

MenuBarExtra 相較於其他的 Scene 比較特別,它不是在一個視窗內顯示內容,而是在系統的 Menu Bar 中顯示 Icon,並可用 menu 或 window 的樣式來呈現內容。只要 App 沒被關掉,即便使用者正在使用其他的 App,使用者仍可透過 MenuBarExtra 來操作 App 的功能。

備註

如果想了解如何實作並使用 MenuBarExtra 的話,可以點擊這裡,我們有另一篇詳細的教學文章。

SwiftUI 的 Window Scene

在建立一個 Window 時,會需要幫它取一個名字,程式會像這樣:

@main
struct XcodeProject: App {
    var body: some Scene {
        Window("XcodeProjectWindow", id: "xcodeProjectWindow") {
            ContentView()
        }
    }
}

這個名字會出現在視窗的上方以及工具列中。

Window Title

當我們試圖叫出 Window 時,如果還未建立,系統就會新增一個,而如果 Window 已經存在的話,則會將現有的 Window 移至最前。

呼叫 SwiftUI Scene 的方法

SwiftUI 在 environment 中提供了一些 callable type 可以用來呼叫 Scene。

環境變數 openWindow

openWindow 可以用來呼叫指定的 WindowGroup 或 Window,用法會像這樣:

@Environment(\.openWindow) private var openWindow
...
openWindow(id: "XcodeProjectWindow")

這裡的 id 要跟 WindowGroup 或 Window 定義時的一樣,系統才知道要呼叫哪一個視窗。

而除了直接使用 id 來指定要開啟哪個視窗,也能使用某個資料來呼叫,用法如下:

@Environment(\.openWindow) private var openWindow
...
openWindow(value: book.id)
...
WindowGroup("Book Details", for: Book.ID.self) { $bookId in
}

這裡傳入的 value 會根據資料的 Type 來開啟對應的視窗。

環境變數 newDocument

newDocument 可以用來新增 FileDocuments 或 ReferenceFileDocuments 檔案,不過會需要定義 DocumentGroup,且檔案類型是可編輯的。

@Environment(\.newDocument) private var newDocument
...
newDocument(TextFile())
...
DocumentGroup(newDocument: TextFile()) { file in
}

環境變數 openDocument

openDocument 可以透過給定檔案位置 URL 來開啟已存在的檔案。

@Environment(\.openDocument) private var openDocument
...
openDocument(at: URL(fileURLWithPath: pathToDocument))
...
struct TextFile: FileDocument {
    static var readableContentTypes: [UTType] { [.plainText] }
}

當然,也一定要有一個 DocumentGroup 並且檔案類型是可讀的。

調整 SwiftUI Scene 的一些 Modifier

commandsRemoved

SwiftUI Scene 預設會提供一些功能在螢幕上方的工具列中,例如開啟視窗,而如果我們想移除這些預設功能的話,就能使用 commandsRemoved。

備註

如果想了解如何實作並使用 commandsRemoved 的話,可以點擊這裡,我們有另一篇詳細的教學文章。

defaultPosition

SwiftUI 的 Scene 在開啟時,預設都會出現在螢幕的正中央,而如果我們想調整這個預設值的話,就能使用 defaultPosition。

備註

如果想了解如何實作並使用 defaultPosition 的話,可以點擊這裡,我們有另一篇詳細的教學文章。

defaultSize

即便 SwiftUI Scene 是可縮放的,我們仍可用 defaultSize 來給定一個預設的視窗寬高。

備註

如果想了解如何實作並使用 defaultSize 的話,可以點擊這裡,我們有另一篇詳細的教學文章。

keyboardShortcut

keyboardShortcut 可以用來設定開啟 Scene 的鍵盤快捷鍵。

備註

如果想了解如何實作並使用 keyboardShortcut 的話,可以點擊這裡,我們有另一篇詳細的教學文章。

分享文章

已複製到剪貼板

主題文章

查看 WWDC22

超級感謝

關於 XcodeProject

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


Contacts

Ricky Chuang

XcodeProject

RickyChuang.xcodeproj@gmail.com

XcodeProject 聯絡

contact.xcodeproj@gmail.com

最新文章