检测iOS暗模式更改

时间:2019-08-29 09:02:39

标签: swift ios13

我通读了有关https://developer.apple.com/documentation/appkit/supporting_dark_mode_in_your_interface

的文档
  

当用户更改系统外观时,系统会自动要求每个窗口和视图重绘自身。在此过程中,系统会为下表列出的macOS和iOS调用几种众所周知的方法来更新您的内容。

在旧版应用程序中,我们在每个类的初始化中将我们的视图创建为惰性变量。这意味着如果用户进入设置并切换到暗模式,则不会以正确的颜色绘制出w。

  

如果您在这些方法之外进行外观敏感的更改,则您的应用可能无法针对当前环境正确绘制其内容。解决方案是将代码移入这些方法。

我们的应用程序很大,将来会进行重构以更好地支持此操作,但是我想知道是否可以通过通知中心检测到此更改,例如Mac OS可以执行的操作:

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

6 个答案:

答案 0 :(得分:9)

快捷键5:

traitCollectionDidChange也被调用了几次。这就是我只检测一次DarkMode运行时更改和setColors()的方式。

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)

        guard UIApplication.shared.applicationState == .inactive else {
            return
        }

        setColors()
    }

在setColors()函数中,我更新了颜色。 检测当前的colorScheme:

extension UIViewController {
    var isDarkMode: Bool {
        if #available(iOS 13.0, *) {
            return self.traitCollection.userInterfaceStyle == .dark
        }
        else {
            return false
        }
    }

}

我有这样定义的颜色(对于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)
        }
    }
}

示例:

private func setColors() {
  myView.backgroundColor = ColorCompatibility.myOlderiOSCompatibleColorName
}

另外,根据您的情况,您可能需要在ViewDidLoad / Will / DidAppear中调用setColors:

viewDidLoad() {
...
setColors()
...
}

对于iOS11 +,您可以使用“资产”中定义的“命名颜色”,并且在IB中更容易使用。

欢呼

答案 1 :(得分:6)

只需覆盖iOS 13中的方法即可检测到暗光模式变化迅速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是ViewControllers和Views中的一种方法。

答案 2 :(得分:2)

在iOS Swift 5中

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
  // Do sonthing
}

答案 3 :(得分:2)

我认为颜色更好使用

UIColor.init { (trait) -> UIColor in

    return trait.userInterfaceStyle == .dark ? .label : .black
}

因为如果系统更改,颜色也会自动更改。

答案 4 :(得分:1)

我最终将所有颜色设置都移至所有视图中的layoutSubviews()函数以及视图控制器中的viewDidLayoutSubviews()。

答案 5 :(得分:1)

Objective-C版本:

if (@available(iOS 12.0, *)) {

    if( self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark ){
       //is dark
    }else{
        //is light

    }
}