alltom.com,
Archive,
Currently Reading,
Have Read,
Micro.blog
Subscribe with RSS or @tom@micro.alltom.com
AnyView is my biggest pet peeve in SwiftUI because:
Let’s say you’re pulling horizontalSizeClass from your @Environment because there’s a UI element that won’t fit in a compact view. So you change:
var fooView: some View {
return Text("foo")
}
to:
var fooView: some View {
if horizontalSizeClass == .compact {
return EmptyView()
} else {
return Text("foo")
}
}
Inexplicably, you get a compiler error: “Function declares an opaque return type, but the return statements in its body do not have matching underlying types.”
It’s worse if the condition is inside another block, like a GeometryReader:
var fooView: some View {
GeometryReader { geometry in
if horizontalSizeClass == .compact {
return EmptyView()
} else {
return Text("foo")
}
}
}
Then you get “Generic parameter ‘Content’ could not be inferred” with a series of “Fix” buttons that just make the problem worse.
The root issue is that View has a type parameter (it’s why fooView’s type is “some View”) that EmptyView and Text set to different values, and the compiler is unwilling to automatically pick a setting of that parameter that is compatible with both.
The fix is to wrap each returned view with AnyView, which sets the parameter to Never:
var fooView: some View {
if horizontalSizeClass == .compact {
return AnyView(EmptyView())
} else {
return AnyView(Text("foo"))
}
}