Sponsor Link
@Environment
既に定義されている Environment
CoreData を使う時の \.managedObjectContext や
シート等を閉じる時の \.presentationMode 等が有名かと思いますが、非常に多くの情報が定義されています。
Apple のドキュメントは、こちら。
斜め読みだけでもしてみると、面白い発見があるかと思います。
Environment 変数の使い方
CoreData を使うコードでは、Environment 経由で ManagedObjectContext を参照します。
変数定義の時に、以下のように @Environment を指定して定義します。
struct ContentView: View {
@Environment(\.managedObjectContext) private var viewContext
...
Environment 変数は、アクセス前に事前にどこかで設定されていなければいけません。多くのシステム定義の変数は、システム側で設定してくれていますが、全てではありません。
設定が必要となる時は、上位のビューで設定して、下位のビューから参照します。上位のビューでは、以下のように .environment を使って設定します。
@main
struct CoreDataAppApp: App {
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
# 上記は、Xcode が生成するテンプレートから引用しています。
自分の Environment を作る
キー値の定義
EnvironmentKey という protocol に準拠する形で定義します。
struct MyEnvironmentKey: EnvironmentKey {
typealias Value = String
static var defaultValue: String = "Default String"
}
参照場所、保存場所を定義
実際に、Environment でアクセスされる場所として EnvironmentValues がありますので、それを拡張するように プロパティとアクセサを定義します。
extension EnvironmentValues {
var myEnvironment: String {
get {
return self[MyEnvironmentKey.self]
}
set {
self[MyEnvironmentKey.self] = newValue
}
}
}
追加した Environment 変数を使ってみる
上位ビューで Environment 設定
//
// MyOwnEnvironmentApp.swift
// MyOwnEnvironment
//
// Created by Tomoaki Yagishita on 2020/10/19.
//
import SwiftUI
struct MyEnvironmentKey: EnvironmentKey {
typealias Value = String
static var defaultValue: String = "Default String"
}
extension EnvironmentValues {
var myEnvironment: String {
get {
return self[MyEnvironmentKey.self]
}
set {
self[MyEnvironmentKey.self] = newValue
}
}
}
@main
struct MyOwnEnvironmentApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.myEnvironment, "Non Default String")
}
}
}
下位ビューで Environment 参照
//
// ContentView.swift
// MyOwnEnvironment
//
// Created by Tomoaki Yagishita on 2020/10/19.
//
import SwiftUI
struct ContentView: View {
@Environment(\.myEnvironment) private var myString
var body: some View {
Text(myString)
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
environment 変数は mutable?
Environment 変数は、immutable です。
下位ビューから、上位ビューに情報を渡すときには、Preference を使うのが、SwiftUI 流です。
以下の記事で、下位のビューから上位のビューに情報を渡す例を紹介しています。
[SwiftUI]Resizableな画像の特定の位置に表示する
まとめ
- EnvironmentKey に準拠するようにキータイプを定義する
- EnvironmentValues を拡張するように、プロパティとアクセサを定義する
説明は以上です。
不明な点やおかしな点ありましたら、ご連絡いただけるとありがたいです。
SwiftUI おすすめ本
SwiftUI を理解するには、以下の本がおすすめです。
# SwiftUI2.0 が登場したことで少し古くなってしまいましたが、いまでも 定番本です。
Sponsor Link