swift 检测iOS暗模式更改

uqjltbpv  于 2023-04-19  发布在  Swift
关注(0)|答案(7)|浏览(347)

我通读了有关以下内容的文档:https://developer.apple.com/documentation/appkit/supporting_dark_mode_in_your_interface
当用户更改系统外观时,系统会自动要求每个窗口和视图重新绘制自己。在此过程中,系统会调用下表中列出的macOS和iOS的几个众所周知的方法来更新内容。
在我们的遗留应用中,我们在每个类的init中创建了我们的视图作为惰性变量。这意味着如果用户进入设置并切换到黑暗模式,视图将不会以正确的颜色绘制出来。
如果您在这些方法之外进行外观敏感更改,您的应用可能无法针对当前环境正确绘制其内容。解决方案是将代码移动到这些方法中。
我们的应用程序相当大,未来将进行重构以更好地支持这一点,但我想知道是否有一种方法可以通过通知中心检测这种变化,就像Mac OS可以做的那样:
How to detect switch between macOS default & dark mode using Swift 3

tyg4sfes

tyg4sfes1#

Swift 5:

traitCollectionDidChange也会被调用几次。这是我检测DarkMode运行时更改和setColors()的方法。

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

        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()
...
}

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

guykilcj

guykilcj2#

只需覆盖iOS 13的方法即可检测暗光模式更改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是ViewControllers和Views中的一个方法。

92dk7w1h

92dk7w1h3#

我觉得对于颜色是更好的使用

UIColor.init { (trait) -> UIColor in

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

因为这样如果系统改变,颜色也会自动改变。

ioekq8ef

ioekq8ef4#

Objective-C版本:

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

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

    }
}
yvfmudvl

yvfmudvl5#

iOS Swift 5

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

wvyml7n56#

如果有人,应用程序被调用traitCollectionDidChange两次,当它被抛出到后台时,下面的代码块将有所帮助。非活动状态是前台(活动)状态的第一步。所以你可以在正确的时间处理主题更改。

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
    
    let userInterfaceStyle = traitCollection.userInterfaceStyle

    if UIApplication.shared.applicationState == .inactive {
        
        switch userInterfaceStyle {
        case .unspecified:
            print("unspecified")
        case .light:
            //Do something for light mode.
            print("Light Mode")
        case .dark:
            //Do something for dark mode.
            print("Dark Mode")
        @unknown default:
            break
        }
    }
}
l7mqbcuq

l7mqbcuq7#

最后我把所有的颜色设置都移到了所有视图中的layoutSubviews()函数和视图控制器中的viewDidLayoutSubviews()。

相关问题