Why Self.Content
is a typealias
while Self.Body
is an associatedtype
? What's the difference?
Because Content
is a typealias
, the author of the ViewModifier
protocol gets to pick the type being aliased when she writes the protocol. (You can't see the type being aliased because that type is _ViewModifier_Content<Self>
. When an identifier in the SDK starts with _
, Apple omits the identifier from documentation and generated interfaces.)
Because Body
is an associatedtype
, you get to pick the type that it aliases, when you write a type that conforms to the ViewModifier
protocol. You can make Body
be any type you want, subject to two conditions:
You must pick a type that conforms to View
(because the ViewModifier
protocol constrains Body
to conform to View
).
You must be able to create or obtain an instance of whatever type you pick, because you have to return an instance of it from the body
method. (Or you could crash or hang to avoid returning at all, but that's usually not what you want…)
So, when you implement a type conforming to ViewModifier
, you cannot influence what Content
means. It always means _ViewModifier_Content<Self>
. But you can choose what Body
means, by choosing the return type of the body
method.
Here's I'll force Body
to mean EmptyView
:
struct EmptyModifier: ViewModifier {
func body(content: Content) -> EmptyView {
EmptyView()
}
}
And here I'll force Body
to mean Color
:
struct RedModifier: ViewModifier {
func body(content: Content) -> Color {
Color.red
}
}
Usually we use some View
as the type, which means that Swift deduces the exact type for us and keeps it a secret:
struct FrameModifier: ViewModifier {
var color: Color
var width: CGFloat
func body(content: Content) -> some View {
return content
.padding(width)
.border(color, width: width)
}
}
Here, all we know about the Body
type is that it conforms to View
. Swift tries pretty hard to keep us from finding out the real type at compile time.