简体   繁体   English

如何以编程方式快速切换到暗模式

[英]How to switch programmatically to dark mode swift

How can I make a switch to change programatically to dark or light mode in my iOS app?如何在我的 iOS 应用程序中切换以编程方式更改为暗模式或亮模式? I'm using Swift.我正在使用斯威夫特。

How can I make a switch to change programatically to dark or light mode in my iOS app?如何在iOS应用中进行切换,以编程方式更改为暗或亮模式? I'm using Swift.我正在使用Swift。

You can use one of the observation ways, for example, Defaults lib, and then add您可以使用其中一种观察方式,例如Defaults lib,然后添加

window.overrideUserInterfaceStyle = .dark window.overrideUserInterfaceStyle = .dark

to

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {} func场景(_场景:UIScene,willConnectTo会话:UISceneSession,选项connectionOptions:UIScene.ConnectionOptions){}

method方法

I want to elaborate more on the answer provided by @Frank Schlegel.我想详细说明@Frank Schlegel 提供的答案。

To change theme from another view controller in your app (which is what you originally asked for, I think) you could add an observer for a UserDefaults value that will trigger the change.要从应用程序中的另一个视图控制器更改主题(我认为这是您最初要求的),您可以为UserDefaults值添加一个观察者,该值将触发更改。

I would add an enum to better represent the theme state我会添加一个枚举以更好地代表主题状态

enum Theme: String {
    case light, dark, system

    // Utility var to pass directly to window.overrideUserInterfaceStyle
    var uiInterfaceStyle: UIUserInterfaceStyle {
        switch self {
        case .light:
            return .light
        case .dark:
            return .dark
        case .system:
            return .unspecified
        }
    }
}

In your SceneDelegate under your window initialisation you have to add this method that is triggered every time UserDefaults changes value.在您的window初始化下的SceneDelegate ,您必须添加每次UserDefaults更改值时触发的此方法。

UserDefaults.standard.addObserver(self, forKeyPath: "theme", options: [.new], context: nil)

Also, you want to remove that observer when the SceneDelegate is deinitialised, add此外,您想在取消SceneDelegate时删除该观察者,添加

deinit {
    UserDefaults.standard.removeObserver(self, forKeyPath: "theme", context: nil)
}

This will place an observer for that theme value in UserDefaults .这将在UserDefaults中放置该theme值的观察者。

To handle changes you need to add this method to your SceneDelegate class.要处理更改,您需要将此方法添加到SceneDelegate类。

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
    guard
        let change = change,
        object != nil,
        keyPath == Defaults.theme.rawValue,
        let themeValue = change[.newKey] as? String,
        let theme = Theme(rawValue: themeValue)?.uiInterfaceStyle
    else { return }

    UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveLinear, animations: { [weak self] in
        self?.window?.overrideUserInterfaceStyle = theme
    }, completion: .none)
}

This will be executed every time theme value changes in UserDefaults and will animate the transition from a theme to another.这将在UserDefaults中的每次theme值更改时执行,并将动画从一个主题到另一个主题的过渡。

Now, to change your theme from other view controllers in your app you just need to change value for UserDefaults .现在,要从应用程序中的其他视图控制器更改主题,您只需更改UserDefaults的值。

UserDefaults.standard.setValue(Theme.light.rawValue, forKey: "theme")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM