見出し画像

Swiftの@から始まる記述が気になってしょうがない人 〜@EnvironmentObject〜

swiftでプログラムを書いてると、@マークの記述がやたら出て来るので、それを調べてみたらAttributeというものだったんですね。それで、swiftで@マークを見たらattributeっていうものなんだなぁと理解してると、どうもそれも違う。@マークにもいろんな役割があるようで。今回は@EnvironmentObjectについて。

使い所

複数のビューで値を共有したい時に使います。ビュー間で値を共有できるグローバル変数といったところでしょうか。

登場人物

この話をするためには、最低でも3人の登場人物が必要です。まずは共有されるデータ、その次に値を共有したいビューが2人。データ、ビュー、ビューが登場人物です。

共有するデータ宣言

共有するデータを宣言するためのクラス宣言をどこかのswiftファイルに書きます。ここでの注意点は二つあります。

  • 共有するデータのクラス宣言には、ObservableObjectプロトコルを適用

  • 共有したい各プロパティには、@Publishedを付けます。

@EnvironmentObjectの説明なのに、なぜか@Publishedが出てきましたが、目的達成(=ビュー間のデータ共有)のためにこれを付けると思ってください。

import Foundation

// ObservableObjectプロトコルを適用し、共有したいプロパティには@Publishedを付ける
class SharedData: ObservableObject {
    @Published var isMyBool = false
}

共有データを参照するビュー

共有データを使用するビューの定義を2つまとめて書いておきます。ここでの注意点は、

  • 各ビューにて、共有データの宣言前に@EnvironmentObjectを指定する(はい、ようやく出ました。)

  • それぞれのビューで使用する共有データのオブジェクト名は、同じでも異なっても問題ない。以下の例では別名を付けています。(myCommonDataとmyCommonData2)

import SwiftUI

struct ContentView: View {
    // 共有オブジェクトを指定する
    @EnvironmentObject var myCommonData: shareData
    
    var body: some View {
        
        VStack {
            Text("最初のビューです")
            Toggle(isOn: $myCommonData.isMyBool){
                Text("\(myCommonData.isMyBool ? "ON":"OFF")")
            }
        }.padding()
        
    }
}

struct SecondView: View {
    // 共有オブジェクトを指定する
    @EnvironmentObject var myCommonData2: shareData
    
    var body: some View {
        VStack{
            Text("2番目のビューです")
            Text("取得したステータス:\(myCommonData2.isMyBool ? "ON" : "OFF")")
        }.padding()
    }
}

呼び出す時の注意点

仕上げです。ビューを呼び出す時は、environmentObject処理を実行するようにします。以下のコードを参照してください。

import SwiftUI

@main
struct shareDataSampleApp: App {
    var body: some Scene {
        WindowGroup {
            VStack
            {
                ContentView()
                SecondView()
            }.environmentObject(shareData())  // ここね。ここよ。
        }
    }
}

結果報告

ビュー1にあるトグルスイッチを変更すると、ビュー2で参照している同じ値も変わっていることが分かります。

トグルスイッチでステータスも変わるの図

まとめ

ビューで値を共有するための一連の仕組みの中で@EnvironmentObjectを使うんですね。他にもObservableObject、@Publishedというキーワードを使いました。

この記事が気に入ったらサポートをしてみませんか?