SwiftUI

2024 年 12 月 31 日

在 SwiftUI 透過 environmentObject 跨多層畫面傳資料

已複製到剪貼板


遵從 ObservableObject protocol 的物件可以使用 environmentObject 來傳遞。

SwiftUI
SwiftUI

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 裡,就不需要額外多寫個參數來承接一個它們用不到的資料。

分享文章

已複製到剪貼板

主題文章

查看 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

最新文章