Issue #693

AppKit app has its theme information stored in UserDefaults key AppleInterfaceStyle, if is dark, it contains String Dark.

Another way is to detect appearance via NSView

struct R {
    static let dark = DarkTheme()
    static let light = LightTheme()

    static var theme: Theme {
        let isDark = UserDefaults.standard.string(forKey: "AppleInterfaceStyle") == "Dark"
        return isDark ? dark : light
    }
}

Another way is to rely on appearance on NSView. You can quickly check via NSApp.keyWindow?.effectiveAppearance but notice that keyWindow can be nil when the app is not active since no window is focused for keyboard events. You should use NSApp.windows.first

let isDark = NSApp.windows.first?.effectiveAppearance.bestMatch(from: [.darkAqua, .vibrantDark]) == .darkAqua

Then build a simple Theme system

import SwiftUI
import EasySwiftUI

protocol Theme {
    var primaryColor: Color { get }
    var textColor: Color { get }
    var text2Color: Color { get }
    var backgroundColor: Color { get }
    var background2Color: Color { get }
}

extension Theme {
    var primaryColor: Color { Color(hex: 0x1) }
}

struct DarkTheme: Theme {
    ...
}

struct LightTheme: Theme {
    ....   
}

For SwiftUI, you can colorScheme environment, then use modifier .id(colorScheme) to force SwiftUI to update when color scheme changes

struct MainView: View {
    @Environment(\.colorScheme)
    var colorScheme

    var body: some View {
        VStack {}
        .id(colorScheme)
    }
}

Updated at 2020-11-10 05:52:33