Separating presentation from content with ViewBuilder
Apple defines ViewBuilder
as “a custom parameter attribute that constructs views from closures.” ViewBuilder
can be used to create custom views that can be used across an application with minimal or no code duplication. In this recipe, we will create a custom SwiftUI view, BlueCircle
, that applies a blue circle to the right of its content.
Getting ready
Let’s start by creating a new SwiftUI project called UsingViewBuilder.
How to do it…
We’ll create our ViewBuilder
in a separate swift file and then apply it to items that we’ll create in the ContentView.swift
file. The steps are given here:
- With our UsingViewBuilder app opened, let’s create a new SwiftUI file by going to File | New | File.
- Select SwiftUI view from the menu and click Next.
- Name the file
BlueCircle
and click Create. - Delete the
#Preview
macro from the file. - Modify the existing struct with the
BlueCircle ViewModifier
:struct BlueCircle<Content: View>: View { let content: Content init(@ViewBuilder content: () -> Content) { self.content = content() } var body: some View { HStack { content Spacer() Circle() .fill(Color.blue) .frame(width:20, height:30) } .padding() } }
- Open the
ContentView.swift
file and try out theBlueCircle ViewBuilder
:var body: some View { VStack { BlueCircle { Text("some text here") Rectangle() .fill(Color.red) .frame(width: 40, height: 40) } BlueCircle { Text("Another example") } } }
- The resulting preview should look like this:
Figure 1.16: ViewBuilder result preview
How it works…
We use the ViewBuilder
struct to create a view template that can be used anywhere in the project without duplicating code. The ViewBuilder
struct must contain a body
property since it extends the View
protocol.
Within the body
property/view, we update the content
property with the components we want to use in our custom view. In this case, we use a BlueCircle
. Notice the location of the content
property. This determines the location where the view passed to our ViewBuilder
will be placed.
See also
Apple documentation on ViewBuilder: https://developer.apple.com/documentation/swiftui/viewbuilder.