web-dev-qa-db-fra.com

Ajout du mode sombre à l'application iOS

J'essaie d'ajouter un thème à mon application (un thème sombre). Ainsi, lorsque l'utilisateur clique sur un commutateur d'activité, l'application entière passe en mode sombre. J'ai codé en dur le mode sombre juste pour voir à quoi il ressemblerait; Cependant, maintenant, j'aimerais pouvoir l'activer et le désactiver via UISwitch, mais je ne sais pas comment procéder. 

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

et puis ce que je fais est d'appeler la fonction dans chacun des contrôleurs de vue pour voir à quoi elle ressemble, mais je dois pouvoir accéder à la valeur bool si le commutateur est allumé ou éteint et s'il est alors nécessaire cette fonction, sinon de simplement garder les choses identiques. Si vous avez d'autres questions, s'il vous plaît faites le moi savoir, je sais que cela pourrait ne pas avoir beaucoup de sens.

5
Jaqueline

Je résoudrais ceci en utilisant Notifications (NSNotificationCenter APIs).

L'idée est de notifier vos contrôleurs de vue en temps réel lorsque le mode sombre est activé et lorsqu'il est désactivé, afin qu'ils puissent également s'adapter à la modification en temps réel. Vous n'avez pas besoin de vérifier l'état du commutateur ou quoi que ce soit du genre.

Commencez par créer deux notifications (vous pouvez également le faire avec une seule et transmettre le thème souhaité dans le dictionnaire userInfo, mais dans ce cas, il est plus facile de créer deux notifications, car vous devez lancer un casting ou non avec 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")
}

Sur tous vos contrôleurs de vue "thématiques", écoutez ces notifications:

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

N'oubliez pas de les supprimer dans deinit, car l'envoi de notifications à des objets non valides déclenche une exception:

deinit {
    NotificationCenter.default.removeObserver(self, name: .darkModeEnabled, object: nil)
    NotificationCenter.default.removeObserver(self, name: .darkModeDisabled, object: nil)
}

Dans vos contrôleurs de vue "thématiques", implémentez darkModeEnabled(_:) et 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
}

Enfin, le basculement de votre commutateur déclenchera l'une des notifications suivantes:

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

}

Avec cela, tous vos contrôleurs de vue seront informés en temps réel lorsque le "thème" changera et ils réagiront en conséquence. Notez que vous devez prendre des mesures pour afficher le bon mode lors du lancement de l'application, mais je suis certain que vous le faites, car vous utilisez UserDefaults et vous les vérifiez probablement. Il convient également de mentionner que NSNotificationCenter n’est pas thread-safe, bien que cela n’ait aucune importance étant donné que tout ce code de l’UI doit de toute façon entrer dans le thread principal.

Pour plus d'informations, vous pouvez consulter la documentation NSNotificationCenter .

Remarque: Ce code est construit sur ce que l'OP avait. Cela peut être simplifié (vous n'avez pas besoin de suivre à la fois les états "clair" et "sombre", par exemple, un seul).

9
Andy Ibanez

Il existe essentiellement deux façons de thématiser votre application. Première voie: utilisez le proxy UIAppearance d’Apple. Cela fonctionne très bien si votre application est très cohérente en matière d'utilisation des couleurs dans toutes vos vues et tous vos contrôles, et moins bien si vous avez un tas d'exceptions. Dans ce cas, je vous recommande d'utiliser un module tiers, tel que SwiftTheme

1
Josh Homann