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"))
}
}