遵從 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,發現眾多技術與框架,讓開發者獲得更多能力。