Change background color when dark mode turns on in SwiftUI

If you want something that works directly from Color (like you're doing with Color.primary), and functions on both iOS and macOS (UIColor won't work on macOS), you can use the following simple Color extension, which uses conditional compilation to work correctly on either OS.

You then simply access these from elsewhere in your code like any other SwiftUI Color. For example:

let backgroundColor = Color.background

No need to check colorScheme or userInterfaceStyle with this approach: The OS will switch automatically when the user moves between Light & Dark mode.

I've also included 'secondary' & 'tertiary' colors, which are a little subjective on macOS, but you can always change them to some of the other NSColor properties if you want.

Swift v5.2:

import SwiftUI

public extension Color {

    #if os(macOS)
    static let background = Color(NSColor.windowBackgroundColor)
    static let secondaryBackground = Color(NSColor.underPageBackgroundColor)
    static let tertiaryBackground = Color(NSColor.controlBackgroundColor)
    #else
    static let background = Color(UIColor.systemBackground)
    static let secondaryBackground = Color(UIColor.secondarySystemBackground)
    static let tertiaryBackground = Color(UIColor.tertiarySystemBackground)
    #endif
}

To elaborate on the two existing answers, there are a couple of approaches to making the background change based on light or dark mode (aka colorScheme) depending on what you're trying to achieve.

If you set the background color to white because that's the default background color, and you want the system to be able to update it when the user switches to dark mode, change .background(Color.white) to .background(Color(UIColor.systemBackground)) (umayanga's answer).

e.g.

// Use default background color based on light/dark mode

struct ContentView: View {
...
var body: some View {

    // ... to any view
    .background(Color(UIColor.systemBackground))

}

If you want to customize the color of a view based on the device being in light or dark mode, you can do this (from Asperi's answer):

// Use custom background color based on light/dark mode

struct ContentView: View {
@Environment(\.colorScheme) var colorScheme

...
var body: some View {

    // ... to any view
    .background(colorScheme == .dark ? Color.black : Color.white)

}

Note that many SwiftUI views set their background color to .systemBackground by default, so if you're using a ScrollView, List, Form, etc, they'll use the default system background color and you won't need to use .background unless you want to customize it.

Tags:

Swiftui