In SwiftUI, @ViewBuilder
is a special attribute used to build views. It is a result builder that allows you to construct views in a more declarative and readable manner. @ViewBuilder
can be used to build complex view hierarchies by composing multiple views together within a single closure.
The @ViewBuilder
attribute can be very useful when creating custom views that need to accept multiple child views, making the code more concise and readable. It is automatically used in many SwiftUI container views like VStack
, HStack
, ZStack
, and ForEach
.
Although the body
property itself doesn’t require @ViewBuilder
, the compiler automatically applies @ViewBuilder
to it, allowing you to write multiple views inside the body without explicitly using a container view.
public protocol View {
associatedtype Body : View
@ViewBuilder var body: Self.Body { get }
}
You can use @ViewBuilder
in different contexts, such as custom view initializers, methods, and computed properties, to enable the same declarative syntax used in SwiftUI’s built-in container views.
Using @ViewBuilder
with initializers allows the creation of views with complex hierarchies directly in the initializer, enabling the passing of multiple child views.
Here’s another example with a custom view initializer:
import SwiftUI
struct CustomContainer<Content: View>: View {
let content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body: some View {
VStack {
content
}
}
}
struct ContentView: View {
var body: some View {
CustomContainer {
Text("This is inside the custom container")
Text("Another view inside the custom container")
}
}
}
In this case, CustomContainer
uses the @ViewBuilder
attribute in its initializer to accept multiple views, allowing you to pass in multiple views when creating an instance of CustomContainer
.
Using @ViewBuilder
with methods encapsulates view-building logic within methods, making it easier to reuse and maintain. Methods can accept parameters, suitable for dynamic or parameterized view generation, allowing the same method to be used with different inputs to produce different views.
Here’s a basic example to illustrate the usage of @ViewBuilder
in methods:
import SwiftUI
struct CustomView: View {
var body: some View {
VStack {
content()
}
}
@ViewBuilder
private func content() -> some View {
Text("Hello from CustomView")
Text("This is another piece of text")
}
}
In this example VStack
is a container that arranges its children in a vertical stack. @ViewBuilder
is applied to the content
function, allowing it to return multiple Text
views without wrapping them explicitly in a container like Group
.
Using @ViewBuilder
with computed properties can be a powerful way to modularize and reuse parts of your SwiftUI views. Suitable for defining view sections that do not require parameters and can be reused within the same view or other views.
struct ContentView: View {
var body: some View {
VStack {
header
bodyContent
footer
}
}
@ViewBuilder
var header: some View {
Text("Header")
.font(.largeTitle)
.padding()
Divider()
}
@ViewBuilder
var bodyContent: some View {
Text("This is the main content area.")
.padding()
Text("You can add more views here.")
.padding()
}
@ViewBuilder
var footer: some View {
Divider()
Text("Footer")
.font(.footnote)
.padding()
}
}