如何检测iOS设备外观变更并更新SwiftUI变量?
Absolutely! You can definitely detect when the device's color scheme changes—let's break down why your current setup isn't working, and how to fix it.
问题根源
Your deviceColorScheme is declared as a let constant, which only gets assigned once when your view initializes. Even though @Environment(\.colorScheme) automatically updates when the system switches between light/dark mode, your constant won't re-calculate its value. That's why it stays stuck on the initial scheme.
解决方案
1. 使用计算属性(最简单的方式)
If you just need a string representation of the current color scheme that updates automatically, replace your constant with a computed property:
@Environment(\.colorScheme) var colorScheme: ColorScheme var deviceColorScheme: String { "\(colorScheme)" }
This works because computed properties don't store a fixed value—they calculate the result every time you access them. Whenever colorScheme updates (from a system appearance change), accessing deviceColorScheme will return the latest string value.
2. 监听变更并执行自定义逻辑
If you need to run additional code when the color scheme changes (like logging, updating other state, or triggering actions), use the .onChange(of:) modifier:
@Environment(\.colorScheme) var colorScheme: ColorScheme @State private var deviceColorScheme: String = "" var body: some View { // Example view that displays the current scheme Text("Current Appearance: \(deviceColorScheme)") .onAppear { // Initialize the value when the view first loads deviceColorScheme = "\(colorScheme)" } .onChange(of: colorScheme) { newScheme in // Update the string when the scheme changes deviceColorScheme = "\(newScheme)" // Add your custom logic here print("Color scheme updated to: \(newScheme)") } }
The .onChange(of: colorScheme) closure triggers immediately whenever the environment's color scheme changes. You can use this to sync your deviceColorScheme variable and run any extra code you need.
关键说明
@Environment(\.colorScheme) is fully reactive in SwiftUI. As long as your view (or properties) depend on its value, SwiftUI will automatically refresh the relevant parts of your UI when the scheme changes. The key is avoiding fixed constants that don't re-evaluate.
内容的提问来源于stack exchange,提问作者Niks Ļeoņenko

