Skip to content

How to use Environment property wrapper in SwiftUI

In SwiftUI, the @Environment property wrapper is a powerful tool designed to manage and propagate shared data across your app’s user interface. It enables views to access environmental information—like interface styles, locale settings, and custom objects—making it easier to respond dynamically to changes. By leveraging @Environment, developers can efficiently pass data through the view hierarchy without cumbersome chains of initializer parameters. This simplifies state management and allows the app to adapt its behavior based on external conditions or internal data changes. In this tutorial, we’ll explore how to effectively utilize the @Environment property wrapper in SwiftUI to create responsive and adaptable applications, focusing on a practical example of theme management with day and night modes.

Step 1: Define the Shared Data

First, let’s create a simple observable object class that will hold our shared data. In this example, it’s a user setting indicating whether it’s night.

@Observable
class UserSettings {
    var isNightTime: Bool = false
}

Step 2: Setup the Main App Structure

We’ll inject our UserSettings into the SwiftUI environment so that all views within the app can access it.

@main
struct MyApp: App {
    @State private var settings = UserSettings()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(settings)
        }
    }
}

Step 3: Create the Main View

ContentView will act as the primary view that modifies the UserSettings.

struct ContentView: View {
   
  @State var settings = UserSettings()
    
    var body: some View {
        
           VStack {
               
               Text("settings.isNightTime: \($settings.isNightTime.wrappedValue)")
               
               Toggle("Toggle Night Mode", isOn: $settings.isNightTime)
               if settings.isNightTime {
                   Text("Night time")
                       .foregroundColor(.white)
                       .padding()
                       .background(Color.black)
               } else {
                   Text("Day time")
                       .foregroundColor(.black)
                       .padding()
                       .background(Color.white)
               }
           }.padding()
        
        
    }
}

This tutorial illustrated how to use the @Environment property wrapper in SwiftUI to manage shared data, such as user preferences for dark or light themes. By leveraging @Environment, we allow for a clean and efficient propagation of data changes across all views that observe the shared object. This approach minimizes the need for passing data through initializers and helps maintain a clear separation of concerns.

Examples of @Environment Use Cases

  • Theme Settings: Apply user-selected themes (like dark mode) across all views.
  • Localization and Accessibility: Adjust text size or localize content based on user settings.
  • User Authentication State: Reflect login status on various UI components.
  • Device Orientation and Size Class: Adapt UI layout based on device orientation and size.
  • Environment Overrides: Customize elements like fonts and colors across multiple views.

Using @Environment simplifies state management, enhances code reusability, and makes the app maintainable by centralizing access to shared data.

Back To Top