I want my icon to be light/dark according to current system color theme, but I never seem to get the dark color image to show, its always the light image that shows up
MenuBarExtra("", image: "my image name") {
Text("some text")
}
also tried using label but the "MenuLogoView" does not get any callback while switching color mode:
MenuBarExtra {
MenuView(model: menuModel)
} label: {
MenuLogoView()
}
struct MenuLogoView: View {
@Environment(\.colorScheme) var colorScheme
...
but "colorScheme" never seems to change
if I use the same image resource in other places of my code it works well for both light/dark color theme modes
It appears that, indeed, MenuBarExtra
s don't get their colorScheme
environment set to the correct value. I'm not sure if this is intentional.
One rather nasty trick is to get the "real" color scheme from one of your View
s in a window.
@State var realColorScheme: ColorScheme = .light
var body: some Scene {
WindowGroup {
ContentView(colorBinding: $realColorScheme)
}
MenuBarExtra {
MenuView(model: menuModel)
} label: {
Image("my_image")
.environment(\.colorScheme, realColorScheme)
}
}
where ContentView
is:
struct ContentView: View {
@Environment(\.colorScheme) var color
@Binding var colorBinding: ColorScheme
var body: some View {
// content here...
.onAppear {
colorBinding = color
}
.onChange(of: color) {
colorBinding = $0
}
}
}
An alternative way is to detect dark mode by reading UserDefaults
with @AppStorage
, described here. This would work even if your app is only a MenuBarExtra
. The user defaults updates a bit more slowly than the @Environment
approach above though, from my experience.
@State var realColorScheme: ColorScheme = .light
@AppStorage("AppleInterfaceStyle") var colorName: String?
var body: some Scene {
MenuBarExtra {
MenuView(model: menuModel)
} label: {
Image("my_image")
.onAppear {
realColorScheme = colorSchemeFromUserDefaultsValue(colorName)
}
.onChange(of: colorName) {
realColorScheme = colorSchemeFromUserDefaultsValue($0)
}
.environment(\.colorScheme, realColorScheme)
}
}
func colorSchemeFromUserDefaultsValue(_ value: String?) -> ColorScheme {
if value == "Dark" {
return .dark
} else {
return .light
}
}