Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change background color when dark mode turns on in SwiftUI

Tags:

swiftui

I've created a custom sheet in SwiftUI with the background color White .background(Color.white)

Now I want the background color to change to black when the user turns on the dark mode on iOS. But I can't find a dynamic color for background like Color.primary for colors of the text etc.

So is there any way to change the background color to black when dark mode turns on?

like image 220
umayanga Avatar asked Jan 11 '20 12:01

umayanga


People also ask

How do I change dark mode in SwiftUI?

To enable dark mode on a Simulator, go to Settings → Developer and toggle Dark Appearance.

How does SwiftUI detect dark mode?

SwiftUI lets us detect whether dark mode or light mode is currently enabled using the colorScheme environment key. If you declare this using @Environment , you can refer to it in your views and they will automatically be reloaded when the color scheme changes.

How do I get the background color in SwiftUI?

SwiftUI has colors that adapt automatically to the color scheme. For example, you can use . background(Color(. textBackgroundColor)) to get an appropriate background color for rendering text regardless of color scheme.

How do I change the background in SwiftUI?

SwiftUI doesn't have a dedicated modifier for displaying background colors or images, but instead lets us specify any kind of background view using its background() modifier. To be clear, you can use any view as your background – another text view if you wanted, for example.


Video Answer


4 Answers

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.

like image 78
ggruen Avatar answered Nov 04 '22 12:11

ggruen


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
}
like image 26
TheNeil Avatar answered Nov 04 '22 13:11

TheNeil


Change the .background(Color.white) to .background(Color(UIColor.systemBackground))

like image 40
umayanga Avatar answered Nov 04 '22 13:11

umayanga


Here is possible approach (for any color)

    struct ContentView: View {
        @Environment(\.colorScheme) var colorScheme
    
        ...
        var body: some View {
    
            // ... to any view
            .background(colorScheme == .dark ? Color.black : Color.white)
    
        }
   }
like image 29
Asperi Avatar answered Nov 04 '22 14:11

Asperi