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

How to switch programmatically to dark mode swift

如何在我的 iOS 应用程序中切换为以编程方式更改为深色或浅色模式? 我正在使用 Swift.

您可以使用 overrideUserInterfaceStyle 属性 覆盖单个视图或视图控制器的样式。但是由于 window 也是一个视图,您可以在主 window 上设置它以强制它进入亮或暗模式:

window.overrideUserInterfaceStyle = .dark

您可以使用其中一种观察方式,例如Defaults lib,然后添加

window.overrideUserInterfaceStyle = .dark

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {}

方法

我想详细说明@Frank Schlegel 提供的答案。

要从您的应用程序中的另一个视图控制器更改主题(我认为这是您最初要求的),您可以为 UserDefaults 值添加一个观察者来触发更改。

我会添加一个枚举来更好地表示主题状态

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
        }
    }
}

SceneDelegatewindow 初始化中,您必须添加每次 UserDefaults 更改值时触发的方法。

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

此外,你想在 SceneDelegate 被取消初始化时删除那个观察者,添加

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

这将在 UserDefaults 中为该 theme 值放置一个观察者。

要处理更改,您需要将此方法添加到您的 SceneDelegate class.

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

每当 theme 值在 UserDefaults 中发生变化时都会执行此操作,并将动画从一个主题过渡到另一个主题。

现在,要从应用中的其他视图控制器更改主题,您只需更改 UserDefaults 的值。

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