traitCollectionDidChange never called on UIView subclass

2.4k Views Asked by At

I have a UIViewController that is presented modally by another UIViewController. This UIViewController has a UITableView with a custom UIView set for it's tableFooterView.

So the issue I am having is: some colors are not displayed properly when switching the device's system appearance. As I have read, cgColor does not adapt automatically to appearance changes:

The color object in this property does not adapt automatically to Dark Mode changes. If you use it to set the color of interface elements, you must update that color yourself when the userInterfaceStyle trait of the current trait collection changes. For information on how to apply color information reliably, see Supporting Dark Mode in Your Interface.

https://developer.apple.com/documentation/uikit/uicolor/1621954-cgcolor

So to tackle this I am overriding the traitCollectionDidChange inside the UIView that uses cgColor like this:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)

        updateView()
    }

In the updateView method, I simply update the cgColor properties of some sub layers, but this method never get called. I tried overriding this method in the superview of the UIView which has the same issue. It only gets called on the UIViewController level which is not useful because the tableFooterView is not set yet at that point in time.

Any ideas how I can solve this?

1

There are 1 best solutions below

0
On

If you want use UIDynamicColor from Assets, you can use it like this:

let newCgColor = someColor.resolvedColor(with: traitCollection).cgColor

For example:

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    imageView?.layer.borderColor = Self.borderColor?.resolvedColor(with: traitCollection).cgColor
}

If it not about problem, you can delete it :)