SwiftUI 如何实现暗模式切换和刷新所有视图

SwiftUI How to implement dark mode toggle and refresh all views

我想实现一个简单的切换以在暗模式和亮模式之间手动切换。但是,我不知道如何在切换开关后让我的应用程序刷新(重绘所有windows)。

到目前为止,我找到了这些答案 and

但这两种解决方案都使用 SceneDelegate.shared,根据此 不推荐。

var isDark: Bool = true {
    didSet { SceneDelegate.shared?.window!.overrideUserInterfaceStyle = isDark ? .dark : .light }
}

难道真的没有其他选择来实现这个吗?我尝试添加 @Environment 变量,但它只在应用程序启动时起作用一次。我需要我的应用程序在切换更改时更新配色方案。

.environment(\.colorScheme, settings.isDarkMode ? .dark : .light)

这是我的开关:

struct SettingsView: View {
    var body: some View {
        Toggle(isOn: $settings.isDarkMode) {
            Text("Night mode")
        }
    }
}

在我的模型中我有这个变量:

@UserDefaultsBacked(key: UserDefaults.Keys.Settings.darkMode, defaultValue: false)
var isDarkMode: Bool

只需将 .colorScheme 添加到顶部视图并添加配色方案变量(@State@Binding 等)。每当变量发生变化时,视图(和子视图)都会自动更新。

struct ContentView: View {
    @State var theColorScheme: ColorScheme = .dark

    func toggleColorScheme() {
        theColorScheme = (theColorScheme == .dark) ? .light : .dark
    }
    
    var body: some View {
        ZStack { // or any other View
            Color.primary // to make the change visible

            Button(action: self.toggleColorScheme) {
                Text("Toggle")
            }
        }   .colorScheme(theColorScheme)
    }
}

注意:如果要更新整个演示文稿的配色方案,最好使用.preferredColorScheme而不是.colorScheme