SwiftUIの@EnvironmentObjectを使ってみる


概要

@EnvironemtObjectについてまとめます。

環境

macOS Big Sur 11.6
Xcode 13.1

公式より

公式より和訳した文章を添付します。

親ビューまたは祖先ビューによって提供される監視可能なオブジェクトのプロパティラッパータイプ。

環境オブジェクトは、監視可能なオブジェクトが変更されるたびに現在のビューを無効にします。

プロパティを環境オブジェクトとして宣言する場合は、environmentObject(_ :)修飾子を呼び出して、対応するモデルオブジェクトを祖先ビューに設定してください。

@EnvironmentObjectを使ってみる

以下の手順で実際に使ってみます。
1. モデルを定義する
1. 全てのViewからモデルにアクセスできるようにする
2. モデルの変更でViewが自動で更新されるようにする

1. モデルを定義する

プロパティの変更を監視できるようにObsavableObjecプロトコルに準拠させます。
Counterクラスのnumberプロパティの値を監視できるように@Publishedを宣言します。

Models/Counter.swift
class Counter: ObservableObject {
    @Published var number: Int = 0
}

2. 全てのViewからアクセスできるように設定する

今回はルートViewにあたるプロジェクト名App.swiftに設定を行います。
environmentObject(_:)モディファーを使います。

プロジェクト名App.swift
@main
struct XXXApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(Counter())
        }
    }
}

3. モデルの変更を検知してViewを自動で更新させる

@EnvironmentObjectで監視可能なクラスを宣言します。

ContentView.swift
struct ContentView: View {
    @EnvironmentObject var counter: Counter

    var body: some View {
        VStack {
            Text(String(counter.number))

            Button("Count Up") {
                counter.number += 1
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(Counter())
    }
}

動作確認

完成すると以下のような動作になると思います。

参考リンク