SwiftUIの@ObservedObjectと@EnvironmentObjectの違いを説明する。
結論
両者とも目的は同じ。やり方が違うだけ。
- 両者とも目的は異なるView間で変数の値を連動させること。
- @ObservedObjectも@EnvironmentObjectを付けてObservableObjectに準拠するclassの型の変数を定義すると、そのclassの@Publishedを付けた変数は異なるView間で値が連動する。
- ObservableObjectに準拠するclassのインスタンスをViewに渡す際のやり方が違う。
– @ObservedObjectは個々のViewにそれぞれインスタンスを渡す。
– @EnvironmentObjectはあるViewに.environmentObject(インスタンス名)でインスタンスを渡す。それだけでそのView内の個々のViewはそのインスタンスと連動する。
具体例
下記Appを例に説明する。
- 親Viewのボタンをタップすると親ViewのヨシヒコのHPが10減る。
- 子Viewのボタンをタップすると子ViewのヨシヒコのHPが10回復する。
- 親Viewと子ViewのヨシヒコのHPは連動して変化する。
![](https://swiftui.kazunoriri.com/wp-content/uploads/2022/08/ObservableObject.gif)
設計イメージ
@ObservedObjectを使う場合
![](https://swiftui.kazunoriri.com/wp-content/uploads/2022/08/image-3-1024x390.png)
@EnvironmentObjectを使う場合
![](https://swiftui.kazunoriri.com/wp-content/uploads/2022/08/image-5-1024x390.png)
コード
@ObservedObjectを使う場合
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(キャラ: ヨシヒコ)
}
}
}
class ゆうしゃ: ObservableObject {
@Published var HP: Int = 100
}
struct 子View: View {
@ObservedObject 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)
}
}
@EnvironmentObjectを使う場合
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)
}
}
差分
左が@ObservedObjectを使う場合、右が@EnvironmentObjectを使う場合
![](https://swiftui.kazunoriri.com/wp-content/uploads/2022/08/スクリーンショット-2022-08-21-9.29.05-1024x818.png)
まとめ
SwiftUIの@ObservedObjectと@EnvironmentObjectの違いを説明した。
コメント