tintColor in SwiftUI
Table of Contents
In the previous article we talk about tintColor. A small but useful property in UIKit. In this article, we will look into accentColor
—an equivalent property in SwiftUI. Let's see whether it can compete with tintColor
.
Theming
Just like tint color, most SwiftUI views rely on accentColor
as their theming mechanic.
The system uses the accent color for common controls and containers.
struct ContentView: View {
@State var progress: CGFloat = 0.5
var body: some View {
VStack(spacing: 20) {
Button("Button") {
}
Slider(value: $progress)
}
}
}
If we don't set it, the accent color is the system default (blue).
You can easily support sarunw.com by checking out this sponsor.
AI Grammar: Correct grammar, spell check, check punctuation, and parphrase.
Override
SwiftUI View has a method accentColor(_ accentColor: Color?)
, which will set the accent color for the view and all of its children.
Sets the accent color for the view and the views it contains.
var body: some View {
VStack(spacing: 20) {
Button("Button 1") {
}
Button("Button 2") {
}
Slider(value: $progress)
}.accentColor(.pink)
}
Hierarchy
Every view inherits accent color from its ancestor. If you want to opt-out of this, you can do that by setting another accent color to that view.
var body: some View {
VStack(spacing: 20) {
Button("Button 1") {
}.accentColor(nil)
Button("Button 2") {
}.accentColor(.green)
Slider(value: $progress)
}.accentColor(.pink)
}
Global accent color
As I mentioned before, the accent color is inherited from an ancestor. So you can apply the same accent color for every view by set accentColor
to an ancestor of all views.
This might vary on your implementation, but for most cases, it should be set in AppDelegate
or SceneDelegate
.
Remove .accentColor(.pink)
from ContentView
.
struct ContentView: View {
@State var progress: CGFloat = 0.5
var body: some View {
VStack(spacing: 20) {
Button("Button 1") {
}.accentColor(nil)
Button("Button 2") {
}.accentColor(.green)
Slider(value: $progress)
}.accentColor(.pink)
}
}
And set it where you initiate ContentView
.
let contentView = ContentView().accentColor(.pink)
window.rootViewController = UIHostingController(rootView: contentView)
How to detect accent color change?
In UIKit, we can detect a change and adjust our view accordingly by override tintColorDidChange()
method. In general, the way SwiftUI use to adapt to change is by using Combine Framework and Built-in Data binding, e.g., @State
, @Binding
, and @ObservedObject
, but accentColor
is just a static var
. At first, I worry that it won't adapt to accent color changes, turn out it can adapt to the change magically.
We start by creating a custom view that shows a rectangle of color from the accent color.
struct MyCustomView: View {
var body: some View {
Rectangle().frame(width: 100, height: 100).foregroundColor(.accentColor)
}
}
In ContentView
.
struct ContentView: View {
var body: some View {
MyCustomView().accentColor(.pink)
}
}
So, a custom view can adapt to the accent color just by using it. Let's try to change accent color dynamically to confirm this behavior.
We set up a view with four buttons that change accent color when click.
struct ContentView: View {
@State var color: Color = .blue
var body: some View {
VStack {
MyCustomView().accentColor(color)
HStack {
Button("Blue") {
self.color = .blue
}
Button("Red") {
self.color = .red
}
Button("Yellow") {
self.color = .yellow
}
Button("Green") {
self.color = .green
}
}
}
}
}
It works flawlessly.
Conclusion
Accent color got everything tint color has, and I think it is far easier to use. I still not sure how a view can listen to accentColor
changes. I expect it to expose this value through @Environment
property, something like:
@Environment(\.accentColor) var accentColor
But, accentColor
can work without any of this. This is quite good, but also a mystery to me. If you know how this magic works, please enlighten me. You can direct message me on Twitter.
You can easily support sarunw.com by checking out this sponsor.
AI Grammar: Correct grammar, spell check, check punctuation, and parphrase.
Related Resources
tintColor – Introduce you to one of an essential part of iOS theming. What is tintColor and its benefit.
Data flow in SwiftUI, Part 1: Data
Data flow in SwiftUI, Part 2: Views as a function of data
Data flow in SwiftUI, Part 3: Tools
Apple Documentation – accentColor
Apple Documentation - accentColor(_:)
Read more article about SwiftUI, tintColor, accentColor, or see all available topic
Enjoy the read?
If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.
Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.
If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.
Become a patron Buy me a coffee Tweet SharetintColor
Introduce you to one of an essential part of iOS theming. What is tintColor and its benefit.
Useful Xcode shortcuts for unit testing
Testing is a process we do along with our development. Knowing shortcuts would help you save some time, which will add up in the long run.