前一篇第 12 天是提到「SwiftUI 中使用 transition Modifier」,雖然本系列文章基本上沒有前後關聯,如果你是還沒讀過前一篇的讀者,也推薦你去讀讀。
EnvironmentObject
在 SwiftUI 中的原理是透過「環境」的概念來達成。我們可以利用這個特性,來達成類似相依性注入的行為。
想要建立一個能傳入作為 EnvironmentObject 的類別,就需要宣告一個繼承 ObservableObject 的類別,在這裡簡單宣告一個:
class MySettings: ObservableObject {
@Published var isActive: Bool = false
}
當要注入的時候,只要像這樣即可:
MyView()
.environmentObject(MySettings())
以上面的範例,在 MyView 中要使用的時候,只要宣告一樣類別的的屬性,要使用的時候就會自動幫忙在環境中查找適合的來用
@EnvironmentObject var mySettings: MySettings
因為是存放在一個「環境」中,所以被賦予的 EnvironmentObject 也能夠自動傳遞下去子畫面。
假使有個子畫面,當 parent view 有被加上一個 environment object ,在子畫面只要宣告,就能夠取用到。
來看範例,我們先建立兩個 View ,顯示上有親子關係:
struct ParentView: View {
@EnvironmentObject var mySettings: MySettings
var body: some View {
VStack {
Text("Parent: \(mySettings.isActive ? "ON" : "OFF" )")
ChildView()
}
}
}
struct ChildView: View {
@EnvironmentObject var mySettings: MySettings
var body: some View {
Text("Child: \(mySettings.isActive ? "ON" : "OFF" )")
}
}
接著在 ContentView 中顯示,並透過 .environmentObject
modifier 來傳入一開始宣告的 MySettings()
struct ContentView: View {
var body: some View {
ParentView()
.environmentObject(MySettings())
}
}
執行後就會像是這樣,可以看到 MySettings 的值都有往下傳遞,而且值都正確。
因為狀態共用的關係,所以透過在子畫面更改狀態,變更狀態的事件也就能自動被傳到有使用這個 environment object 的畫面,進而更新畫面。
來改一下 ChildView 成這樣
struct ChildView: View {
@EnvironmentObject var mySettings: MySettings
var body: some View {
VStack {
Text("Child: \(mySettings.isActive ? "ON" : "OFF" )")
Button {
mySettings.isActive.toggle()
} label: {
Text("切換")
.font(.system(size: 14, weight: .semibold))
.padding(.horizontal, 16)
.padding(.vertical, 4)
}
.tint(.white)
.background(
RoundedRectangle(cornerRadius: 8)
.foregroundColor(.indigo)
)
}
.padding(.horizontal, 16)
.padding(.vertical, 8)
.background(
RoundedRectangle(cornerRadius: 10)
.stroke(lineWidth: 1)
.foregroundColor(.gray)
.opacity(0.3)
)
}
}
可以看到在 第 8 行 就是更改 mySettings.isActive 的布林值:
mySettings.isActive.toggle()
點擊切換就換會像是這樣的效果:
像是這些情境都可以用到:
到這裡就是在 SwiftUI 中如何使用 EnvironmentObject 。
那今天的 SwiftUI 的大大小小就到這邊,以上,明天見!
本篇使用到的 UI 元件和 modifiers 基本上沒有受到版本更新影響
因此 Xcode 14 等環境下使用也是沒問題的。