Jon_Shier
(Jon Shier)
1
While SwiftUI is somewhat off topic here, I've run into what I think is a fundamental language question. I've recently stumbled across a way to make SwiftUI body properties more dynamic, and I'm not quite sure how it works at all. Say I have a view and I'd like to make the body dynamic:
struct DynamicView: View {
let condition: Bool
var body: some View {
if condition {
return Text("Text")
} else {
return Rectangle()
}
}
}
Of course this fails to compile due to not returning the same type through the opaque generic. However, adding @ViewBuilder to body lets it compile and, perhaps more shockingly, appears to work correctly.
struct DynamicView: View {
let condition: Bool
@ViewBuilder
var body: some View {
if condition {
return Text("Text")
} else {
return Rectangle()
}
}
}
I thought @_functionBuilder types had to be applied to, you know, functions. All I can think of is that it's somehow being applied to body's getter, which I didn't think was possible.
1 Like
mayoff
(Rob Mayoff)
2
@ViewBuilder effectively converts your body to this:
var body: some View {
if condition {
return _ConditionalContent<Text, Rectangle>(first: Text("Text"))
} else {
return _ConditionalContent<Text, Rectangle>(second: Rectangle())
}
}
So both branches return a value of type _ConditionalContent<Text, Rectangle>.
You cannot do this transformation manually because _ConditionalContent has internal visibility.
You can use Group instead of the @ViewBuilder annotation:
var body: some View {
Group {
if condition {
Text("Text")
} else {
Rectangle()
}
}
}
2 Likes
Jon_Shier
(Jon Shier)
3
I’m familiar with the mechanics of how @ViewBuilder works. My question was more about how the builder is being applied to a property which is not a function.
mayoff
(Rob Mayoff)
4
Oh. Well, it's in the proposal:
A function builder type can be used as an attribute in two different syntactic positions. The first position is on a func , var , or subscript declaration. For the var and subscript , the declaration must define a getter, and the attribute is treated as if it were an attribute on that getter. The func , var , or subscript may not be a protocol requirement or any other sort of declaration which does not define an implementation. A function builder attribute used in this way causes the function builder transform to be applied to the body of the function; it is not considered part of the interface of the function and does not affect its ABI.
1 Like