IT工房くまや

通称くまが運営するIT工房サイト

SwiftUIの@Observableと@Environmentについて調べてみました

SwiftUIの@Observableをクラスに適用すると、そのクラスを@EnvironmentでViewに導入すると、そのクラスのプロパティに変更を加えた時その変更を随時Viewに適用してくれます。

下記コードはTestObservableクラスに@Observableを適用し、ContentViewに@Environmentでそのクラスを導入したものです。

旧姓、新姓のボタンをクリックすると、クラスのnameプロパティを変化させます。その変化に対応しクラスのnameプロパティをセットしたTextの表示が変化します。

PreviewもViewにenvironmentでクラスを導入することで、Previewも変化します。

import SwiftUI

struct ContentView: View {
    @Environment(TestObservable.self) var testObservable
    
    var body: some View {
        Text(testObservable.name)
        Button {
            testObservable.changeName(name: "旧姓")
        } label: {
            Text("旧姓")
        }
        Button {
            testObservable.refreshName()
        } label: {
            Text("新姓")
        }
    }
}

@Observable
class TestObservable {
    var name: String
    
    init() {
        self.name = "新姓"
    }
    
    func refreshName() {
        self.name = "新姓"
    }
    
    func changeName(name: String) {
        self.name = name
    }
}

#Preview {
    ContentView()
        .environment(TestObservable())
}

@mainからの呼び出しは下記の感じです。

import SwiftUI

@main
struct SwiftUILearnApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(TestObservable())
        }
    }
}