1

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?

Tomer Ciucran
  • 199
  • 1
  • 10
  • I would double-check your `updateView()` func... maybe put a `print("trait change")` statement in your `traitCollectionDidChange` function. This is working fine for me: https://gist.github.com/DonMag/220cb07468ca8699be056a1f6d5719b7 – DonMag Mar 27 '20 at 13:30
  • I am pretty sure it's not being called, testing it with breakpoint, unless there is a chance that it's not stopping at the breakpoint even though it's executed. – Tomer Ciucran Mar 27 '20 at 14:56
  • 1
    Hmm... I updated that gist with a complete example. `PresentTestViewController` has a button that presents `TraitTestViewController`, which has a tableView with an instance of `TraitView` as its `.tableFooterView`. All via code - just set a view controller to `PresentTestViewController` -- https://gist.github.com/DonMag/220cb07468ca8699be056a1f6d5719b7 – DonMag Mar 27 '20 at 15:48
  • This is interesting, I put your code in a new project and yes it works as expected. I am gonna look deeper into my code to see if anything else causes this. Thank you. – Tomer Ciucran Mar 27 '20 at 16:16

1 Answers1

0

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 :)

iTux
  • 1,946
  • 1
  • 16
  • 20