この記事では、@EnvironmentObjectの使い方について解説していきたいと思います。
@EnvironmentObject とは?
@EnvironmentObjectは、@ObservedObjectと同じことができます。
@ObservedObjectは各Viewでインスタンス化して、その次のViewにはインスタンスを渡して変数にアクセスしていました。
しかし、今回の@EnvironmentObjectは一度インスタンス化してしまえば、いちいちインスタンスを渡さずに、全ての画面からアクセスすることができます。
図解するとこのようなイメージです。

使い方
使い方は、@ObservedObjectとそれほど変わりません。
ObservableObjectを準拠させたclass内に、@Publishedで変数を宣言して、それを各Viewからアクセスします。
注意点が、プロジェクト名App.swift内のContentViewに.environmentObject()でインスタンスを紐付けします。これを忘れてしまうとエラーになってしまいます。
@main
struct SampleProjectApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(Fruits())
}
}
}
あとは、@ObservedObjectのように、使えます。
class Fruits: ObservableObject {
@Published var name = "りんご"
@Published var price = 100
}
struct ContentView: View {
@EnvironmentObject var fruits: Fruits
var body: some View {
VStack {
Text("\(fruits.name)一個\(fruits.price)円です")
.padding()
Button("10円値上げする") {
fruits.price += 10
}
}
}
}
まず、プロジェクト名App.swift内の.environmentObject(Fruits())でインスタンスを生成しています。
生成さえれできれば、どこのViewでも@EnvironmentObject var fruits: Fruitsと記載することで、アクセスできます。
以下のように、他のViewでも同じように@EnvironmentObject var fruits: Fruitsと記載することで、データにアクセスできます。
class Fruits: ObservableObject {
@Published var name = "りんご"
@Published var price = 100
}
struct ContentView: View {
@EnvironmentObject var fruits: Fruits
@State var isShowBView = false
var body: some View {
VStack {
Text("\(fruits.name)一個\(fruits.price)円です")
.padding()
Button("10円値上げする") {
fruits.price += 10
}
.padding()
Button("BViewへ遷移") {
isShowBView = true
}
}
.sheet(isPresented: $isShowBView) {
BView()
}
}
}
struct BView: View {
@EnvironmentObject var fruits: Fruits
var body: some View {
Button("みかんに変える") {
fruits.name = "みかん"
}
}
}
まとめ
@EnvironmentObjectは、アプリ内全体でデータを共有したいときに使うカスタム属性です。使い方は、@ObservedObjectとそれほど変わらず、ObservableObjectプロトコルに準拠したclassを定義し、その中で@Publishedをつけて変数を宣言します。そして、プロジェクト名App.swiftでインスタンスを生成し、使いたいViewで@EnvironmentObject var fruits: Fruitsというふうに記載するだけです。

