Recently I came across an interesting(may be naive) problem regarding UIColor in Swift..
import UIKit
let view = UIView(frame: CGRect(x: 0,
y: 0,
width: 50,
height: 50))
view.backgroundColor = .systemBlue
let a = UIColor.systemBlue
switch a {
case .red:
print("red")
case .systemBlue:
print("blue")
default:
print("unknown")
}
Following code prints "blue" on playground perfectly fine, but changing
let a = UIColor.systemBlue
to
let a = view.backgroundColor ?? .red
prints "unknown" in playground, May someone help what is happening here? I could not resolve it.. Is it something related to value type or reference type at some point?? Please help!!
Printing the two values gives you the explanation:
print(UIColor.systemBlue)
<UIDynamicSystemColor: 0x600000b47880;
name = systemBlueColor
>
print(view.backgroundColor!)
<UIDynamicModifiedColor: 0x60000058bed0;
contrast = normal,
baseColor = <UIDynamicSystemColor: 0x600000b47880;
name = systemBlueColor
>
>
When setting the backgroundColor
property, UIKit wraps the color in a private class UIDynamicModifiedColor
.
If you compare the resolved colors using the view's traits, you'll get true
:
UIColor.systemBlue.resolvedColor(with: view.traitCollection) ==
view.backgroundColor!.resolvedColor(with: view.traitCollection)
The resolved color is an absolute color:
print(UIColor.systemBlue.resolvedColor(with: view.traitCollection))
UIExtendedSRGBColorSpace 0 0.478431 1 1
A color such as UIColor.systemBlue
is a dynamic color that might result in different colors, depending on the view's traits, which include factors such as high-contrast mode and dark/light mode.
From the docs of UIColor.systemBlue
:
A blue color that automatically adapts to the current trait environment.