2024 年 12 月 31 日
iOS iPadOS macOS Swift SwiftUI tvOS visionOS watchOS在 SwiftUI 透過 environmentObject 跨多層畫面傳資料
遵從 ObservableObject protocol 的物件可以使用 environmentObject 來傳遞。
ObservableObject 概覽
在使用 SwiftUI 開發 App 時,我們可能會遇到一種情況,會需要把資料從上層傳到底層,過程中會經過很多都不需要使用這個資料的 View,那很直接地讓所有 View 都加個參數,一路傳下去的做法就有點笨也麻煩。這時就能使用 Environment 來傳遞資料。
注意
不過 ObservableObject 已經算是舊的寫法了,Apple 在 WWDC23 推出了 Observable,主要用來取代 ObservableObject,它提供了更方便、更簡單的使用方式,也在畫面更新上做了優化。
用 environmentObject 來傳遞 ObservableObject
SwiftUI 要透過 environmentObject 來傳遞資料的話,可以分成以下三個步驟:
步驟一:讓資料型別遵從 ObservableObject
遵從 ObservableObject protocol 並不需要額外實做什麼,唯一要做的是,在我們想擁有 State 功能的變數前,加上 @Published,這樣這個資料改變時,畫面也會跟著更新。
class Profile: ObservableObject {
@Published var name: String
var id: UUID
...
}
步驟二:在擁有資料的上層畫面使用 environmentObject
用 environmentObject 可以讓這整個 View Hierarchy 都能存取這個資料,也就是 ContentView 以下的所有子 View、子子 View、子子子 View⋯⋯。
@main
struct Example: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.environmentObject(ProfileService.currentProfile)
}
}
假設 ProfileService 是一個 Singleton,而它有一個變數 currentProfile 的型別就是遵從 ObservableObject 的 Profile。
步驟三:在需要資料的地方使用 EnvironmentObject
在需要取用資料的 View 裡,使用 EnvironmentObject property wrapper 就能順利拿到上層傳下來的資料了!
struct ContentView: View {
@EnvironmentObject private var profile: Profile
var body: some View { ... }
}
在過程中會經過的所有 View 裡,就不需要額外多寫個參數來承接一個它們用不到的資料。
關於 XcodeProject
XcodeProject 創立於 2023,致力於協助開發者探索 Apple 的創新世界,學習在 iOS、iPadOS、macOS、tvOS、visionOS 與 watchOS 上開發 App,發現眾多技術與框架,讓開發者獲得更多能力。