この記事では、@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
というふうに記載するだけです。