【SwiftUI】@EnvironmentObjectの使い方を徹底解説

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