Attempting to reference the @Environment objects horizontalSizeClass and verticalSizeClass on macOS (native, not Catalyst) results in the following errors:
'horizontalSizeClass' is unavailable in macOS
'verticalSizeClass' is unavailable in macOS
I appreciate that these properties aren't really applicable for macOS, but this presents a big barrier to creating SwiftUI Views which work universally (i.e. cross-platform across macOS, iOS, etc.).
One workaround is to wrap all the size-class-specific code inside conditional compilation, but the result is lots of duplication and redundancy (see below example).
Isn't there a more efficient way to handle this?
Example Universal View:
struct ExampleView: View {
#if !os(macOS)
@Environment(\.horizontalSizeClass) var horizontalSizeClass
#endif
private var item1: some View {
Text("Example Item 1")
}
private var item2: some View {
Text("Example Item 2")
}
private var item3: some View {
Text("Example Item 3")
}
var body: some View {
VStack {
#if !os(macOS)
if horizontalSizeClass == .compact {
VStack {
item1
item2
item3
}
} else {
HStack {
item1
item2
item3
}
}
#else
HStack {
item1
item2
item3
}
#endif
}
}
}
It's true that macOS doesn't support
horizontalSizeClassandverticalSizeClassnatively, but the good news is it's easy to add them.You can define your own
@Environmentobjects by making astructthat conforms toEnvironmentKey, then using it to extendEnvironmentValues.All you need to implement size classes on macOS is the following. They just return
.regularat all times, but it's enough to function exactly the same as on iOS.With this in place, you don't need anything special for macOS. For example:
You can even put these extensions into a framework for broader use, so long as you define them as
public.