Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI: Get the Dynamic Background Color (Dark Mode or Light Mode)

Is there a way to systematically access the standard, dynamic background color for SwiftUI views, regardless of whether the user be in Light or Dark Mode?

For example, I know the following can be used to get the primary (e.g. text) color:

let textColor = Color.primary

...but I don't see anything similar for getting the background color.

let backgroundColor = Color.??? // Not available

I'm looking for something that works on both iOS and macOS.

like image 553
TheNeil Avatar asked Mar 13 '20 14:03

TheNeil


People also ask

How do I know if I have dark mode SwiftUI?

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 change the background color in SwiftUI main view?

To add a screen background view by putting it at the bottom of the ZStack. Text("Hello, SwiftUI!") <1> Use ZStack so we can place a background view under the content view. <2> Use color view as background.

How do I use SwiftUI dark mode?

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

What is UIColor?

UIColor provides a list of class properties that create adaptable and fixed colors such as blue, green, purple, and more. UIColor also offers properties to specify system-provided colors for UI elements such as labels, text, and buttons.


1 Answers

So there doesn't currently appear to be any such property built into SwiftUI's OS-independent Color class; however, UIColor and NSColor do provide accessors for it (on iOS and macOS respectively), and you can use these older color objects to initialize a SwiftUI Color object.

As a result, what you need can be achieved using a simple extension to Color, such as the below, which uses conditional compilation to work correctly on either OS.

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
}

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

let backgroundColor = Color.background
like image 190
TheNeil Avatar answered Sep 17 '22 08:09

TheNeil