SwiftUIにおける変数の扱い方【View間のデータ渡しEnvironmentObject】
@EnvironmentObjects
一度インスタンス化すればインスタンス化したViewの下位層であれば参照可能なプロパティラッパー(property wrappers)。
- App層で最初に表示するViewで定義した場合、すべてのViewで使用可能となる。
struct SwiftSampleApp: App {
var body: some Scene {
WindowGroup {
ContentView().environmentObject(Sound())
}
}
}
@ObservedObjectとの違い
@ObservedObjectは、
親Viewでインスタンス化し子Viewに引数で渡して使用します。
@EnvironmentObjectはViewの上位層のどこかのViewインスタンス時に、environmentObject修飾子を使用して設定していればその下位層のどのViewでも直接アクセスすることが可能です。
使用したいViewで@EnvironmentObject
を使用して宣言することでenvironmentObject修飾子で設定したモデルデータにアクセスできます。
@EnvironmentObject var sound: Sound
使用方法
➀使用したい変数(クラス)、メンバ変数をObservableObject、Publishedを使用して定義
class Sound: ObservableObject {
@Published var isMute: Bool = false
@Published var volume = 10
}
②使用したいViewを生成する際に.environmentObject() でEnvironmentObjectsのモデルオブジェクトを紐づけ。Appで初めのViewインスタンスを紐づけると全てのViewで使用可能となる。
@main
struct SampleProjectApp: App {
var body: some Scene {
WindowGroup {
ContentViewEnvironmentObject().environmentObject(Sound())
}
}
}
③使用したいViewでEnvironmentObjectで定義。
struct ContentViewEnvironmentObject: View {
@EnvironmentObject var sound: Sound
var body: some View {
VStack {
Button(action: {
sound.isMute.toggle()
}) {
Image(systemName: sound.isMute ? "speaker.wave.3.fill" : "speaker.slash.fill")
}
Text(sound.isMute ? "On" : "Off")
}
}
}
使用したいView内で使用できるようになります。
実行イメージ
公式にも記載されていますが、監視したいオブジェクトがObservablプロトコルに準拠している場合はEnvironmentを使用しenvironment(;)か、Environmental(:_:)修飾子を使用してモデルオブジェクトをビューに設定します。
公式サイト