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:
-
ThemeKeyis a customEnvironmentKeywith adefaultValueof.light. It is used to provide a default theme for the environment. - The
EnvironmentValuesextension includes a newthemeproperty. It uses the customThemeKeyto get or set the theme. -
Themeis an enumeration that describes the possible themes, which arelightanddark. - The
thememethod extension onViewlets you apply a theme to any view by setting thethemeenvironment value. -
ThemedViewis a view that adjusts its appearance based on the currentthemeenvironment value. It reads this value using the@Environmentproperty wrapper. -
ContentViewcontains aButtonthat toggles thethemebetweenlightanddark. This change is passed down toThemedViewvia thethemeenvironment value.
By using environment values, you can efficiently share common state and behavior between views, simplifying your code and making your views more reusable.