SwiftUIのObservableObject/@Published/@StateObject/@EnvironmentObjectの意味を説明する。
結論
View間で変数の値を連動できる。
- ObservableObject準拠のclass内で@Publishedを付けた変数を定義し、
- @StateObjectでそのclassのインスタンスを生成する。
- Viewを返すstructで@EnvironmentObjectを付け上記のclassに準拠した変数を定義する。
- あるViewに.environmentObject(2で生成したインスタンス)と記述する。
- 以上により4のViewの範囲で2で生成したインスタンスの変数の変化に3のViewが連動する。※3で生成するViewは何個有っても良く全てのViewで変数の値は連動する。
具体例
下記Appを例に説明する。
- 親Viewのボタンをタップすると親ViewのヨシヒコのHPが10減る。
- 子Viewのボタンをタップすると子ViewのヨシヒコのHPが10回復する。
- 親Viewと子ViewのヨシヒコのHPは連動して変化する。
設計イメージを示す。
実際のコードを示す。
import SwiftUI
struct ContentView: View {
@StateObject var ヨシヒコ = ゆうしゃ()
var body: some View {
HStack {
// 親View
VStack {
Text("親View")
Text("ヨシヒコのHP : \(String(ヨシヒコ.HP))")
Button("ヨシヒコを攻撃") { ヨシヒコ.HP -= 10 }
.buttonStyle(.borderedProminent)
}
.padding()
.frame(width: 200)
// 子View
子View()
}
.environmentObject(ヨシヒコ)
}
}
class ゆうしゃ: ObservableObject {
@Published var HP: Int = 100
}
struct 子View: View {
@EnvironmentObject var キャラ: ゆうしゃ
var body: some View {
VStack {
Text("子View")
Text("ヨシヒコのHP : \(String(キャラ.HP))")
Button("ヨシヒコを回復") { キャラ.HP += 10 }
.buttonStyle(.borderedProminent)
}
.padding()
.frame(width: 200)
.border(Color.black, width: 1)
}
}
まとめ
SwiftUIのObservableObject/@Published/@StateObject/@EnvironmentObjectの意味を説明した。
コメント