DEV Community

Rizwan
Rizwan

Posted on • Originally published at blog.rizwan.dev on

SwiftUI Color Scheme

In UIKit app, If you would like to change the color scheme within the app. Setting UserInterfaceStyle object to your root window would help.

Take a look at NetNewsWire iOS app. It gives Appearance settings where you can choose your color palette for the app. These are the possible options

  • Automatic: respects system color scheme and changes whenever user switching between light and dark mode from the OS
  • Light: Light mode for the whole app and didn’t respect the system color scheme
  • Dark: dark mode for the whole app and didn’t respect the system color scheme
func updateUserInterfaceStyle() {
  switch AppDefaults.userInterfaceColorPalette {
    case .automatic:
      window!.overrideUserInterfaceStyle = .unspecified
    case .light:
      window!.overrideUserInterfaceStyle = .light
    case .dark:
      window!.overrideUserInterfaceStyle = .dark
  }
}

Setting unspecified makes the app respects the system-wide color scheme here.

SwiftUI Way

SwiftUI gives us an environment variable and preferred color scheme modifier to change the color scheme.

struct ContentView: View {
    @State var preferredColorScheme: ColorScheme? = nil

    var body: some View {
        List {
                Button(action: {
                preferredColorScheme = .light
            }) {
                HStack {
                    Text("Light")
                    Spacer()
                    if preferredColorScheme == .light {
                        selectedImage
                    }
                }
            }

            Button(action: {
                preferredColorScheme = .dark
            }) {
                HStack {
                    Text("Dark")
                    Spacer()
                    if preferredColorScheme == .dark {
                        selectedImage
                    }
                }
            }
        }
        .listStyle(InsetGroupedListStyle())
        .preferredColorScheme(preferredColorScheme)
        .navigationBarTitle("ColorScheme Test")
    }

    var selectedImage: some View {
        Image(systemName: "checkmark")
            .foregroundColor(.blue)
    }
}

In the above code, we are setting the preferredColorScheme modifier to our content view and changing it via @State object. It will give us one view with two options where you can change the color scheme.

It’s also possible with the environment value like below

@main
struct ColorSchemeTestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environment(\.colorScheme, .dark)
        }
    }
}

We can also get to know the currently selected color scheme via environment object like below.

@Environment(\.colorScheme) var colorScheme

NOTE

As of beta 2, there is no way that I can find, to set the colorScheme to unspecified to get automatic behaviour. I have even filed a Feedback. In case if you find a way to achieve it, let me know at twitter

I did create a sample project to explain the behaviour and you can find it here at Github.

Links

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

Qodo Takeover

Introducing Qodo Gen 1.0: Transform Your Workflow with Agentic AI

Rather than just generating snippets, our agents understand your entire project context, can make decisions, use tools, and carry out tasks autonomously.

Read full post

Best practices for optimal infrastructure performance with Magento

Running a Magento store? Struggling with performance bottlenecks? Join us and get actionable insights and real-world strategies to keep your store fast and reliable.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️