はじめに
SwiftUIでは EnvironmentValues
を利用して、ビュー間で値を共有できます。通常は @Environment
プロパティラッパーを使って EnvironmentValues
にアクセスしますが、独自のプロパティを追加したい場合は EnvironmentValues
を拡張することができます。
本記事では、 EnvironmentValues
の拡張方法と、カスタムプロパティの追加方法、さらに ビュー階層ごとに異なる environment(_:)
を適用する方法 について詳しく解説します。
EnvironmentValues の基本
EnvironmentValues
には dismiss
や colorScheme
など、SwiftUIにおける環境情報が格納されています。
@Environment(\.dismiss) private var dismiss
@Environment(\.colorScheme) private var colorScheme
このように @Environment
プロパティラッパーを使うことで、ビュー内で簡単に環境情報を取得できます。
EnvironmentValues を拡張する
では、 EnvironmentValues
を拡張してカスタムプロパティを追加する方法を見ていきましょう。
例: isDarkModeEnabled
を追加する
EnvironmentValues
に isDarkModeEnabled
というカスタムプロパティを追加し、 @Environment
を使ってビューで簡単に呼び出せるようにします。
1. カスタムプロパティの定義
まずは EnvironmentKey
を使って isDarkModeEnabled
を定義します。このプロパティは、アプリ全体でダークモードのオン・オフを簡単に管理できるようにするものです。
private struct IsDarkModeEnabledKey: EnvironmentKey {
static let defaultValue: Bool = false
}
extension EnvironmentValues {
var isDarkModeEnabled: Bool {
get { self[IsDarkModeEnabledKey.self] }
set { self[IsDarkModeEnabledKey.self] = newValue }
}
}
2. @Environment
で取得して利用する
カスタム環境値を @Environment
を使ってビュー内で利用できるようになります。
struct ContentView: View {
@Environment(\.isDarkModeEnabled) private var isDarkModeEnabled
var body: some View {
VStack {
Text(isDarkModeEnabled ? "ダークモード" : "ライトモード")
.padding()
Button("モードを切り替え") {
// 直接変更はできない
}
}
}
}
しかし、このコードでは @Environment
で取得した値は 読み取り専用 なので、直接変更することはできません。
EnvironmentValues
を変更する方法
environment(_:)
を使って親ビューから設定する
@Environment
は直接変更できませんが、親ビューで @State
を使って環境値を制御し、 environment(_:)
を使って下位ビューに渡すことができます。
1. ParentView
で @State
を定義し、environment(_:)
で渡す
struct ParentView: View {
@State private var isDarkModeEnabled = false
var body: some View {
ContentView()
.environment(\.isDarkModeEnabled, isDarkModeEnabled)
}
}
2. ContentView
では @Binding
を使う
struct ContentView: View {
@Binding var isDarkMode: Bool
var body: some View {
VStack {
Text(isDarkMode ? "ダークモード" : "ライトモード")
.padding()
Button("モードを切り替え") {
isDarkMode.toggle()
}
}
}
}
environment(_:)
で特定のネスト以下だけ値を変更する
SwiftUI では environment(_:)
を使うことで、特定のネストされたビューのみ環境値を上書きすることができます。
struct ParentView: View {
@State private var isDarkModeEnabled = false
var body: some View {
VStack {
Text("ParentView: \(isDarkModeEnabled ? \"Dark\" : \"Light\")")
.padding()
NestedView()
.environment(\.isDarkModeEnabled, true) // NestedView 以降はダークモード
}
.environment(\.isDarkModeEnabled, isDarkModeEnabled)
}
}
このように environment(_:)
を使うことで、特定のネスト以下だけ異なる環境設定を適用できます。
まとめ
本記事では、 EnvironmentValues
を拡張してカスタムプロパティを追加する方法について解説しました。
-
EnvironmentKey
を利用してカスタムプロパティ (isDarkModeEnabled
) を定義する -
EnvironmentValues
を拡張し、新しいプロパティを追加する -
@Environment
を使ってビュー内で取得・利用する -
environment(_:)
を活用してビュー階層ごとに異なる設定を適用する