Logo for tanaschita.com

Dynamic colors in SwiftUI

Learn to use the asset catalog or the programmatic approach to define dynamic colors in SwiftUI.

08 Nov 2021 · 4 min read

SwiftUI offers a range of predefined semantic colors we can use in our views. But in most cases, we want to define our own custom colors that automatically adapt to certain user preferences like dark mode changes.

This can be achieved by using the asset catalog or programmatically.

Using the asset catalog to define dynamic colors for SwiftUI views

Defining dynamic colors via the asset catalog can be achieved with the following steps:

  1. Open the Assets.xcassets file that was created with the iOS project.
  2. Add colors by using the + button.
  3. Configure dark mode colors by opening the Attributes Inspector and select Any, Dark in the Appearances dialog.
Sponsorship logo
Preparing for a technical iOS job interview - updated for iOS 17
Check out my book on preparing for a technical iOS job interview with over 200 questions & answers. Test your knowledge on iOS topics such as Swift, SwiftUI, Combine, HTTP Networking, Authentication, SwiftData & Core Data, Concurrency with async/await, Security, Automated Testing, Machine Learning and more.
LEARN MORE

After doing that, we will be presented with a new color dark mode setting.

Color Asset Catalog
Color Asset Catalog

To use the defined color in a SwiftUI view, we initialize the Color with its catalog name:

.foregroundColor(Color(named: "error"))

It will automatically adjust to dark mode changes.

The programmatic approach to define dynamic colors for SwiftUI views

To achieve the same results programmatically, we can make use of the UITraitCollection class which represents the interface environment for our iOS app.

UIColor provides an initializer that takes a closure which gets called when the interface environment like a dark mode setting changes.

public init(dynamicProvider: @escaping (UITraitCollection) -> UIColor)

Knowing that, we can create a utility method:

extension UIColor {
static func dynamicColor(light: UIColor, dark: UIColor) -> UIColor {
guard #available(iOS 13.0, *) else { return light }
return UIColor { $0.userInterfaceStyle == .dark ? dark : light }
}
}

And use it to define dynamic colors programmatically.

struct ColorScheme {
var error: Color {
return color(light: UIColor(red: 0.7, green: 0.1, blue: 0.1, alpha: 1),
dark: UIColor(red: 0.9, green: 0.1, blue: 0.1, alpha: 1))
}
private func color(light: UIColor, dark: UIColor) -> Color {
return Color(UIColor.dynamicColor(light: light, dark: dark))
}
}

SwiftUI's Color class itself does not provide the trait collection initializer, but as we can see above, we can simply convert the UIKit's UIColor to SwiftUI's Color type.

Now, we can use the created color scheme in our SwiftUI views.

.foregroundColor(colorScheme.error)
Sponsorship logo
Preparing for a technical iOS job interview - updated for iOS 17
Check out my book on preparing for a technical iOS job interview with over 200 questions & answers. Test your knowledge on iOS topics such as Swift, SwiftUI, Combine, HTTP Networking, Authentication, SwiftData & Core Data, Concurrency with async/await, Security, Automated Testing, Machine Learning and more.
LEARN MORE

Newsletter

Image of a reading marmot
Subscribe

Like to support my work?

Say hi

Related tags

Articles with related topics

swiftdata

swiftui

swift

ios

How to store images in SwiftData

Learn how to efficiently store larger amounts of data in SwiftData.

27 Nov 2023 · 1 min read

Latest articles and tips

© 2024 tanaschita.com

Privacy policy

Impressum