How to gracefully adapt dark mode in Swift
References:
- Swift to judge the system version number of several methods
- IOS13 – Night Mode/Dark Mode
Dynamic color
From iOS13 onwards, the UIColor class has added the following methods:
extension UIColor {
@available(iOS 13.0.*)
public init(dynamicProvider: @escaping (UITraitCollection) - >UIColor)
}
Copy the code
We can use this method to create dynamic colors, but always use it based on the iOS version number.
To avoid trouble, I wrote a ColorUtil class
class ColorUtil {
public class func dynamicColor(dark:UIColor.light:UIColor) - >UIColor {
if #available(iOS 13.*) { // The version number is greater than or equal to 13
return UIColor { (traitCollection: UITraitCollection) - >UIColor in
return traitCollection.userInterfaceStyle = = UIUserInterfaceStyle.dark ?
dark : light
}
}
return light
}
}
Copy the code
Listen for mode changes
Can use the following UIViewController. TraitCollectionDidChange to listen:
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?). {
if #available(iOS 13.*) {
if self.traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
if self.traitCollection.userInterfaceStyle = = .dark {
// Night mode
} else {
// Daytime mode}}}}Copy the code
Set the dynamic color of the NavigationBar
There are two ways to modify the NavigationBar style:
- Modify the
NavigationBar.backgroundColor
- through
NaivgationBar.setBackgroundImage(UIImage? , for: UIBarMetrics)
Setting the background image
If the method of modifying backgroundColor is used, the background image will be overlaid, so we need to consider setting the background image to nil, that is:
self.navigationController?.navigationBar.setBackgroundImage(nil, for: UIBarMetrics.default)
self.navigationController?.navigationBar.backgroundColor = yourDynamicColor
Copy the code
If you use the method of modifying the background image, you cannot use dynamic colors, but should modify the background image dynamically in traitCollectionDidChange.