I read through the documentation regarding: https://developer.apple.com/documentation/appkit/supporting_dark_mode_in_your_interface
When the user chan
in iOS Swift 5
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
// Do sonthing
}
I ended up moving all my color setup to layoutSubviews() function in all views and the viewDidLayoutSubviews() in the view controllers.
Just override method form iOS 13 to Detect dark light mode change swift 5
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if #available(iOS 13.0, *) {
if self.traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
if traitCollection.userInterfaceStyle == .dark {
//Dark
}
else {
//Light
}
}
} else {
// Fallback on earlier versions
}
}
traitCollectionDidChange is a method in ViewControllers and Views.
Objective-C version:
if (@available(iOS 12.0, *)) {
if( self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ){
//is dark
}else{
//is light
}
}
Swift 5:
traitCollectionDidChange also gets called a few times. This is how I detect DarkMode runtime change and setColors() only once.
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
guard UIApplication.shared.applicationState == .inactive else {
return
}
setColors()
}
In setColors() func I update the colors. Detecting current colorScheme:
extension UIViewController {
var isDarkMode: Bool {
if #available(iOS 13.0, *) {
return self.traitCollection.userInterfaceStyle == .dark
}
else {
return false
}
}
}
I have colors defined like this (for iOS < 13):
enum ColorCompatibility {
static var myOlderiOSCompatibleColorName: UIColor {
if UIViewController().isDarkMode {
return UIColor(red: 33, green: 35, blue: 37, alpha: 0.85)
}
else {
return UIColor(hexString: "#F3F3F3", alpha: 0.85)
}
}
}
Example:
private func setColors() {
myView.backgroundColor = ColorCompatibility.myOlderiOSCompatibleColorName
}
Also you might need to call setColors in ViewDidLoad/Will/DidAppear depending on your case like this:
viewDidLoad() {
...
setColors()
...
}
For iOS11+ you could use "named Colors", defined in Assets and much easier to use in IB.
Cheers
I think for colors is better to use
UIColor.init { (trait) -> UIColor in
return trait.userInterfaceStyle == .dark ? .label : .black
}
because this way if the system change, the color change too automatically.