Search code examples
swiftuiviewuikituicolorswift-playground

Mysterious UIColor behaviour with UIView and in General in Swift


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!!


Solution

  • 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.