How to change UIColor according to UserInterfaceStyle(Dark Mode/Light Mode) in UIView extension in swift [5+]?

641 Views Asked by At

I was creating the method in UIView extension and I needed to change UIColor according to UIUserInterfaceStyle i.e. separate UIColor for both Dark & Light mode Interface.

Usually, in UIViewController class traitCollectionDidChange method is triggered whenever UIUserInterfaceStyle is changed and we can determine the current user interface style by

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    DispatchQueue.main.async { [weak self] in
        guard let self = self else { return }
        self.changeUIWithUserInterface(style: self.traitCollection.userInterfaceStyle)
    }
}

But the Extension of UIView does not have traitCollectionDidChange method that can be triggered

so how can I change the UIColor according to UIUserInterfaceStyle in UIView extension?
I figured it out and thought to post it for fellow devs.

Hope It Helps :)

2

There are 2 best solutions below

0
On BEST ANSWER

Below method works like a charm for me!
It is triggered whenever traitCollection changes..
It can work on any extension of various UI components

UIColor.init { (trait) -> UIColor in
    return trait.userInterfaceStyle == .dark ? darkModeColor : lightModeColor
}

You have to check for iOS 13+, if you are working with support of iOS versions below 13, which you can check easily

if #available(iOS 13.0, *) {
    //Dark mode is supported 
    self.backgroundColor = UIColor.init { (trait) -> UIColor in
        return trait.userInterfaceStyle == .dark ? darkModeColor : lightModeColor
    }
} else {
    //Earlier version of iOS, which does not suppport dark mode.
    self.backgroundColor = lightModeColor
}

Reference: Thanks to answer of @ElanoVasconcelos

1
On

You can set UIColor as simple variable, that automatically changes when traitCollection changes:

struct ColorPalette {

public static var subtitleColor: UIColor = {
    if #available(iOS 13, *) {
        return UIColor { (UITraitCollection: UITraitCollection) -> UIColor in
            if UITraitCollection.userInterfaceStyle == .dark {
                return UIColor.lightText
            } else {
                return .darkGray
            }
        }
    } else {
        /// Return a fallback color for iOS 12 and lower.
        return .darkGray
    }
  }()
}

Usage:

label.textColor = ColorPalette.subtitleColor