Fügen Sie ein dunkles Thema in iOS hinzu

Hallo alle zusammen!

Mein Name ist Andrey, ich bin vom My Broker-Team. Ich werde Ihnen sagen, dass Unterstützung für ein dunkles Thema in iOS hinzugefügt wurde.

Apple in iOS 13 hat ein dunkles Thema für das gesamte System hinzugefügt. Benutzer können in den iOS-Einstellungen ein helles oder dunkles Erscheinungsbild auswählen. Im Dunkelmodus verwendet das System eine dunklere Farbpalette für alle Bildschirme, Ansichten, Menüs und Steuerelemente.

Bild

Wen kümmert es - geh unter die Katze.

Unterstützung für dunkles Design


Die in Xcode 11 standardmäßig erstellte Anwendung unterstützt Dark Design in iOS 13. Für die vollständige Implementierung des Dark-Modus müssen Sie jedoch zusätzliche Änderungen vornehmen:

  • Farben sollten helles und dunkles Design unterstützen
  • Bilder sollten helles und dunkles Design unterstützen

Apple hat mehrere Systemfarben hinzugefügt, die helles und dunkles Design unterstützen.
Bild

In iOS 13 wurde der neue UIColor- Initialisierer eingeführt :

init (dynamicProvider: @escaping (UITraitCollection) -> UIColor)

Fügen Sie eine statische Funktion hinzu, um Farbe mit Unterstützung für das Umschalten zwischen hellem und dunklem Design zu erstellen:

extension UIColor {
    
    static func color(light: UIColor, dark: UIColor) -> UIColor {
        if #available(iOS 13, *) {
            return UIColor.init { traitCollection in
                return traitCollection.userInterfaceStyle == .dark ? dark : light
            }
        } else {
            return light
        }
    }
}

CGColor unterstützt kein automatisches Umschalten zwischen Hell und Dunkel. Sie müssen die CGColor nach dem Ändern des Designs manuell ändern .

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)
        
    layer.borderColor = UIColor.Pallete.black.cgColor
}

Es ist auch möglich, Farbe für dunkle Dekoration in Ressourcen hinzuzufügen.

Bild

Aber ich ziehe es vor, dem Code Farben hinzuzufügen.

UIColor.Pallete
extension UIColor {
    
    struct Pallete {

        static let white = UIColor.color(light: .white, dark: .black)
        static let black = UIColor.color(light: .black, dark: .white)

        static let background = UIColor.color(light: .white, dark: .hex("1b1b1d"))
        static let secondaryBackground = UIColor(named: "secondaryBackground") ?? .black

        static let gray = UIColor.color(light: .lightGray, dark: .hex("8e8e92"))

    }
}


Fügen Sie für Bilder einfach eine Variante des Bildes für ein dunkles Design direkt in den Ressourcen hinzu.

Bild

Lassen Sie uns eine kleine Anwendung für ein Beispiel machen.


Die Anwendung enthält zwei Fenster und drei Bildschirme.

Erstes Fenster: Autorisierungsbildschirm.

Zweites Fenster: Multifunktionsleistenbildschirm und Benutzerprofilbildschirm.

Screenshots in hellem und dunklem Design
Bild Bild Bild
Bild Bild Bild

Wechseln Sie zwischen hellen und dunklen Themen


Erstellen Sie eine Aufzählung für das Thema:


enum Theme: Int, CaseIterable {
    case light = 0
    case dark
}

Wir fügen die Möglichkeit hinzu, das aktuelle Thema zu speichern, um es nach dem Neustart der Anwendung wiederherzustellen.

extension Theme {
    
    //   UserDefaults
    @Persist(key: "app_theme", defaultValue: Theme.light.rawValue)
    private static var appTheme: Int
    
    //    UserDefaults
    func save() {
        Theme.appTheme = self.rawValue
    }
    
    //   
    static var current: Theme {
        Theme(rawValue: appTheme) ?? .light
    }
}

Fortdauern
@propertyWrapper
struct Persist<T> {
    let key: String
    let defaultValue: T
    
    var wrappedValue: T {
        get { UserDefaults.standard.object(forKey: key) as? T ?? defaultValue }
        set { UserDefaults.standard.set(newValue, forKey: key) }
    }
    
    init(key: String, defaultValue: T) {
        self.key = key
        self.defaultValue = defaultValue
    }
}


Um das Design zu erzwingen, müssen Sie den Stil aller Anwendungsfenster ändern.

Wir implementieren Theme Switching in der Anwendung.


extension Theme {
    
    @available(iOS 13.0, *)
    var userInterfaceStyle: UIUserInterfaceStyle {
        switch self {
        case .light: return .light
        case .dark: return .dark
        }
    }
    
    func setActive() {
        //   
        save()
        
        guard #available(iOS 13.0, *) else { return }
        
        //       
        UIApplication.shared.windows
            .forEach { $0.overrideUserInterfaceStyle = userInterfaceStyle }
    }
}

Es ist auch erforderlich, den Fensterstil auf das aktuelle Thema zu ändern, bevor das Fenster angezeigt wird.

extension UIWindow {
    
    //     
    //     
    func initTheme() {
        guard #available(iOS 13.0, *) else { return }
        
        overrideUserInterfaceStyle = Theme.current.userInterfaceStyle
    }
}

Screenshots zur Auswahl eines hellen oder dunklen Themas
Bild Bild

Fügen Sie dem Systemthema einen Schalter hinzu


Fügen Sie dem Aufzählungsthema ein Systemthema hinzu.
enum Theme: Int, CaseIterable {
    case system = 0
    case light
    case dark
}

Nach der erzwungenen Installation eines hellen oder dunklen Themas kann nicht festgestellt werden, welches Design im System enthalten ist. Um das Systemdesign zu erkennen, fügen wir der Anwendung ein Fenster hinzu, in dem wir die Designänderung nicht erzwingen. Es ist auch erforderlich, eine Designänderung zu implementieren, wenn in der Anwendung ein Systemthema installiert ist und der Benutzer das Design in iOS ändert.

final class ThemeWindow: UIWindow {
    
    override public func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {

        //         iOS,     .
        // :      .
        if Theme.current == .system {
            Theme.system.setActive()
        }
    }
}

let themeWindow = ThemeWindow()

class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        ...
        //    ,    
        //       
        themeWindow.makeKey()
        ...
        return true
    }
}

extension Theme {
    
    @available(iOS 13.0, *)
    var userInterfaceStyle: UIUserInterfaceStyle {
        switch self {
        case .light: return .light
        case .dark: return .dark
        case .system: return themeWindow.traitCollection.userInterfaceStyle
        }
    }
    
    func setActive() {
        //   
        save()
        
        guard #available(iOS 13.0, *) else { return }
        
        //       
        //        
        UIApplication.shared.windows
            .filter { $0 != themeWindow } 
            .forEach { $0.overrideUserInterfaceStyle = userInterfaceStyle }
    }
}

Screenshots zur Auswahl eines Systems, eines hellen oder dunklen Themas
Bild Bild

Ergebnis


Unterstützung für dunkles Design und Umschalten zwischen System-, hellen und dunklen Themen.
Bildschirm Video


Link zum gesamten Projekt

All Articles