'SwiftUI custom accentColor not working on physical device(iOS 13) but works everywhere else(iOS 14.0+)

In my SwiftUI View I've an Image that I've loaded from assets. I've set the foregroundColor to accentColor, which I've also set in asset as my custom AccentColor which is to be used throughout the app.

Asset:

asset

ContentView body:

var body: some View {
    Image("MyImageName")
        .resizable()
        .renderingMode(.template)
        .foregroundColor(.accentColor)
        .frame(width: 32, height: 32, alignment: .center)
}

The preview and the simulator show the image in the right foregroundColor. But, while running on a physical device the foregroundColor somehow remain the default blue accentColor of the phone.

Preview:

Simulator:

Real Device:

Why does this happen? And how do I make sure the AssentColor work across devices no matter the iOS version without modifying any settings on the iPhone? Debug details: The device iOS version is iOS 13.5.1 and Xcode 12.0.1.



Solution 1:[1]

So, while testing further I found that even though accentColor is available from iOS 13.0, customizing accentColor is only available from iOS 14.0. So I created an extension to use the accentColor from asset manually in iOS 13 and work normally in iOS 14.0 and above.

extension Color {

    static var accent: Color {
        if #available(iOS 14.0, *) {
            return accentColor
        } else {
            return Color(#colorLiteral(red: 0.5, green: 0.5, blue: 0.5, alpha: 1))
        }
    }
}

Solution 2:[2]

Color.accentColor works fine, even changing it on a View with .accentColor(newColor) works on iOS 13.

The only problem is that iOS 13 doesn't set Color.accentColor to the color in the assets specified by ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME.

What worked for me was to do that step manually by simply setting the window.tintColor to that color:

if #available(iOS 14, *) {} else {
  window.tintColor = UIColor(named: "AccentColor")
}

Solution 3:[3]

I wanted to leave a reminder here that the global app tint color can be broken by accessing properties of the application (including selection color, tint colors, etc) or constructing some views before the application creates the first UIWindow.

If tint color is broken everywhere (including in the simulator) make sure you're not trying to construct or access UIKit components before your first window, including third party SDKs. In my app, a third-party crash logging SDK was breaking the accent color.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 fphilipe
Solution 3 Matt Gallagher