Creating & Accessing Environment Values in SwiftUI
Written by Team Kodeco
Managing the state of your user interface is a crucial part of any SwiftUI application. In SwiftUI, environment values are one of the mechanisms provided to handle shared state across multiple views. Environment values can be accessed or set from anywhere in the view hierarchy and are particularly useful for sharing common data or functionality.
Consider an example in which you create a custom environment value to dynamically change the theme of your app:
// Defining a custom environment value
struct ThemeKey: EnvironmentKey {
static let defaultValue: Theme = .light
}
extension EnvironmentValues {
var theme: Theme {
get { self[ThemeKey.self] }
set { self[ThemeKey.self] = newValue }
}
}
// Enum for the different themes
enum Theme {
case light, dark
}
extension View {
func theme(_ theme: Theme) -> some View {
environment(\.theme, theme)
}
}
struct ThemedView: View {
@Environment(\.theme) var theme: Theme
var body: some View {
VStack {
if theme == .light {
Text("Light Theme")
.foregroundColor(.black)
.background(Color.white)
} else {
Text("Dark Theme")
.foregroundColor(.white)
.background(.black)
}
}
.padding()
}
}
struct ContentView: View {
@State var theme: Theme = .light
var body: some View {
VStack {
Button("Switch Theme") {
// Setting our custom environment value
switch theme {
case .dark:
theme = .light
case .light:
theme = .dark
}
}
ThemedView()
}
.theme(theme)
}
}
Your preview should look like this:
In the above code:
-
ThemeKey
is a customEnvironmentKey
with adefaultValue
of.light
. It is used to provide a default theme for the environment. - The
EnvironmentValues
extension includes a newtheme
property. It uses the customThemeKey
to get or set the theme. -
Theme
is an enumeration that describes the possible themes, which arelight
anddark
. - The
theme
method extension onView
lets you apply a theme to any view by setting thetheme
environment value. -
ThemedView
is a view that adjusts its appearance based on the currenttheme
environment value. It reads this value using the@Environment
property wrapper. -
ContentView
contains aButton
that toggles thetheme
betweenlight
anddark
. This change is passed down toThemedView
via thetheme
environment value.
By using environment values, you can efficiently share common state and behavior between views, simplifying your code and making your views more reusable.