将黑暗模式添加到iOS应用程序

Jaq*_*ine 13 themes uiswitch ios swift

我正在尝试为我的应用添加一个主题(一个黑暗的主题).因此,当用户点击活动开关时,它将使整个应用程序进入黑暗模式.我对黑暗模式进行了硬编码只是为了看看它会是什么样子; 但是现在我希望能够通过和UISwitch启用和禁用它,但我不知道该怎么做?

class DarkModeTableViewCell: UITableViewCell {

var DarkisOn = Bool()
let userDefaults = UserDefaults.standard


@IBOutlet var darkModeSwitchOutlet: UISwitch!

override func awakeFromNib() {
    super.awakeFromNib()


}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}


@IBAction func darkModeSwitched(_ sender: Any) {

    if darkModeSwitchOutlet.isOn == true {

        //enable dark mode

        DarkisOn = true

        userDefaults.set(true, forKey: "DarkDefault")
        userDefaults.set(false, forKey: "LightDefault")



    } else {

        //enable light mode
        DarkisOn = false

        userDefaults.set(false, forKey: "DarkDefault")
        userDefaults.set(true, forKey: "LightDefault")
    }

}



}



class DarkModeViewController: UIViewController {



func set(for viewController: UIViewController) {



    viewController.view.backgroundColor = UIColor(red: 0.1, green: 0.1, blue: 0.1, alpha: 1.0)
        viewController.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
    viewController.navigationController?.navigationBar.tintColor =     UIColor.white
    viewController.navigationController?.navigationBar.barStyle =     UIBarStyle.black
    viewController.tabBarController?.tabBar.barStyle = UIBarStyle.black






}
static let instance = DarkModeViewController()
}
Run Code Online (Sandbox Code Playgroud)

然后我所做的就是在每个视图控制器中调用该函数来查看它的外观,但是如果开关处于打开或关闭状态,我需要能够访问bool值,如果是,则需要它该功能,否则只是保持相同.如果您有任何其他问题,请告诉我,我知道其中一些可能没有多大意义.

And*_*nez 19

我将使用通知(NSNotificationCenterAPI)解决此问题.

我们的想法是在启用暗模式和禁用暗模式时实时通知您的视图控制器,这样他们也可以实时适应变化.您无需检查交换机的状态或类似的内容.

首先创建两个通知(您也可以只使用一个通知并在userInfo字典中传入所需的主题,但在这种情况下,创建两个通知更容易,因为您需要使用Swift进行强制转换).

NotificationsName+Extensions.swift:

import Foundation

extension Notification.Name {
    static let darkModeEnabled = Notification.Name("com.yourApp.notifications.darkModeEnabled")
    static let darkModeDisabled = Notification.Name("com.yourApp.notifications.darkModeDisabled")
}
Run Code Online (Sandbox Code Playgroud)

在所有"可设置"视图控制器上,收听以下通知:

    override func viewDidLoad() {
        super.viewDidLoad()

        // Add Observers
        NotificationCenter.default.addObserver(self, selector: #selector(darkModeEnabled(_:)), name: .darkModeEnabled, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(darkModeDisabled(_:)), name: .darkModeDisabled, object: nil)
    }
Run Code Online (Sandbox Code Playgroud)

不要忘记删除它们deinit,因为向无效对象发送通知会引发异常:

deinit {
    NotificationCenter.default.removeObserver(self, name: .darkModeEnabled, object: nil)
    NotificationCenter.default.removeObserver(self, name: .darkModeDisabled, object: nil)
}
Run Code Online (Sandbox Code Playgroud)

在"themable"视图控制器中,实现darkModeEnabled(_:)darkModeDisabled(_:):

@objc private func darkModeEnabled(_ notification: Notification) {
    // Write your dark mode code here
}

@objc private func darkModeDisabled(_ notification: Notification) {
    // Write your non-dark mode code here
}
Run Code Online (Sandbox Code Playgroud)

最后,切换开关将触发任一通知:

@IBAction func darkModeSwitched(_ sender: Any) {

    if darkModeSwitchOutlet.isOn == true {
        userDefaults.set(true, forKey: "darkModeEnabled")

        // Post the notification to let all current view controllers that the app has changed to dark mode, and they should theme themselves to reflect this change.
        NotificationCenter.default.post(name: .darkModeEnabled, object: nil)

    } else {

        userDefaults.set(false, forKey: "darkModeEnabled")

        // Post the notification to let all current view controllers that the app has changed to non-dark mode, and they should theme themselves to reflect this change.
        NotificationCenter.default.post(name: .darkModeDisabled, object: nil)
    }

}
Run Code Online (Sandbox Code Playgroud)

这样,当"主题"发生变化时,所有视图控制器都会实时通知,并会相应地做出反应.请注意,您需要采取措施在应用程序启动时显示正确的模式,但我确信您正在这样做,因为您正在使用UserDefaults并且可能会检查它们.另外值得一提的是NSNotificationCenter不是线程安全的,尽管它应该无关紧要,因为无论如何都应该在主线程中的所有UI代码.

有关更多信息,请查看NSNotificationCenter文档.

注意:此代码基于OP所具有的.它可以简化(您不需要跟踪"亮"和"暗"状态,例如,只有一个).

  • @Woodstock`viewDidLoad`在视图实际可见之前被调用。在将视图显示给用户之前,将应用暗模式。 (2认同)

Jos*_*ann 5

基本上有两种方法可以为您的应用程序设置主题。方法一:使用Apple的UIAppearance代理。如果您的应用在所有视图和控件中的颜色使用情况都非常一致,那么效果很好,如果有很多例外,效果就不太好。在这种情况下,我建议使用第三方插件,例如SwiftTheme


Mr.*_*ani 5

从iOS 13苹果启动的深色主题,如果要在iOS应用中添加深色主题,可以在viewDidLoad()上应用以下代码行:

        if #available(iOS 13.0, *) {
            overrideUserInterfaceStyle = .dark
        } else {
            // Fallback on earlier versions
        }
Run Code Online (Sandbox Code Playgroud)

因此,您可以更改主题,例如有2个选项为浅色或深色主题。但是,如果您正在编写上述代码,则仅在运行iOS 13的设备上,它总是采用深色主题。

overrideUserInterfaceStyle = .light
Run Code Online (Sandbox Code Playgroud)

或者,如果您的设备已经在iOS 13上运行,则可以更改主题,例如:

在此处输入图片说明

您甚至可以检查当前设置的主题,例如:

if self.traitCollection.userInterfaceStyle == .dark{
    print("Dark theme")
 }else{
    print("Light theme")
}
Run Code Online (Sandbox Code Playgroud)

让我们来看一个例子:

override func viewDidLoad() {
       super.viewDidLoad()

       if self.traitCollection.userInterfaceStyle == .dark{
           self.view.backgroundColor = UIColor.black
       }else{
            self.view.backgroundColor = UIColor.white
  }

}
Run Code Online (Sandbox Code Playgroud)

结果:

在此处输入图片说明

在此处输入图片说明

这是相同的视频: https : //youtu.be/_k6YHMFCpas