Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting iOS Dark Mode Change

Tags:

swift

ios13

I read through the documentation regarding: https://developer.apple.com/documentation/appkit/supporting_dark_mode_in_your_interface

When the user changes the system appearance, the system automatically asks each window and view to redraw itself. During this process, the system calls several well-known methods for both macOS and iOS, listed in the following table, to update your content.

In our legacy app we create our views as lazy variables in the init of each class. This means the views won't get drawn out with the correct color if the user goes into settings and switches to dark mode.

If you make appearance-sensitive changes outside of these methods, your app may not draw its content correctly for the current environment. The solution is to move your code into these methods.

Our application is quite big and a refactor will be done to support this in a better way in the future but I'm wondering if there is a way to detect this changes with the notification center like what can be done for Mac OS:

How to detect switch between macOS default & dark mode using Swift 3

like image 513
andromedainiative Avatar asked Aug 29 '19 09:08

andromedainiative


People also ask

How does Swift Detect dark mode or light mode?

SwiftUI makes it really simply to detect when dark mode is enabled. We simply have to add a @Enviroment variable and use . colorScheme property to scan the settings on our device and see if dark mode is enabled.

How do I know if dark mode is enabled iOS?

Dark mode can be detected by using the userInterfaceStyle property on the current trait collection. When it's set to dark you know that the current appearance is set to dark.

How do you test dark mode in Simulation?

To see the dark-mode-rendered version, click on the Dark Mode toggle. To see the email in a larger view, click on the “view in full screen” button. Now you can edit the code and view the dark mode rendered view side by side.

How do I bypass dark mode?

Open System Settings. Navigate to Developer Options. Scroll down the Hardware accelerated rendering section and enable the Override force-dark/Force dark mode* option.


2 Answers

Swift 5:

traitCollectionDidChange also gets called a few times. This is how I detect DarkMode runtime change and setColors().

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {         super.traitCollectionDidChange(previousTraitCollection)          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

like image 70
Sasho Avatar answered Sep 30 '22 18:09

Sasho


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.

like image 24
Hardik Thakkar Avatar answered Sep 30 '22 17:09

Hardik Thakkar