Understanding Result Builders & View Builders in SwiftUI Part 2

abdul ahad
5 min readMar 5, 2024

--

Photo by Ian Valerio on Unsplash

if you haven’t read about resultBuilders you can read about it here part1.

@ViewBuilder, based on@ResultBuilders, are a type of domain-specific language (DSL) that helps constitute what we call today SwiftUI. They are used to collect child views and combine them into a final View which is then returned. if we look at the definition@ViewBuilderin detail it uses the @ResultBuilder under the hood.

let’s see how SwiftUI uses ViewBuilder

ViewBuilder in View protocol (body of any SwiftUI View)

@ViewBuilder is a function builder in SwiftUI that allows you to create views by composing smaller views. It is used to construct views from closures and is an integral part of SwiftUI's design, allowing for more readable and maintainable code when creating complex view hierarchies.

public protocol View {
associatedtype Body : View
@ViewBuilder var body: Self.Body { get }
}

the View protocol uses the @ViewBuilder attribute for its body property. what does this mean? This means that any SwiftUI struct conforming to View protocol can use @ViewBuilder to define its body. so in short ViewBuilder allows the body to create custom views that can build and combine other views to create complex layouts.

Let’s dig deeper with examples

lets look at different View builder methods in more detail

EmptyView

if we have an empty view the View builder will use the method below to handle an empty view.

public static func buildBlock() -> EmptyView

we can verify this in the debugger and we can see the type returned is an EmptyView.

Single View

if we have a single view, the View builder will use the method below to handle a single view.

public static func buildBlock<Content>(_ content: Content) -> Content where Content : View

we can verify this in the debugger and we can see the type returned is a Text.

MultipleViews

let’s take a VStack as an example for multiple views

if you also look into the VStack init function definition below you will see it uses@ViewBuilderto combine child views into one View.

The VStack initializer takes a closure as a parameter, and that closure is marked as @ViewBuilder. This allows us to write a number of expressions inside — each of which represents a view. In essence, the closure passed to the stack builds a list of views, which become subviews of the stack in this example.

//Vstack init definition
@inlinable public init(alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content)

Looking at the declaration of the ViewBuilder struct, we can see the method below for handling a list of two or more views:

public static func buildBlock<each Content>(_ content: repeat each Content) -> TupleView<(repeat each Content)> where repeat each Content : View

As we can see from the return type, this constructs a TupleView wrapping our two views: the image and the text.

let's also see an example of multiple Child Views

here we can see we have every child view wrapped in a TupleView.

We can think of a view builder as a mechanism to construct a tuple view that represents lists of views.Everything is combined to be a single view at the end which the body of SwiftUI view requires.

Conditional Content

You can also use view builders to construct dynamic Views. Here’s how we can conditionally include a view:

we can see that the VStack still has two subviews: an image, and an optional text. From this view tree, SwiftUI knows that the stack will always have an image as the first subview, and perhaps a text as the second subview.

we can also use other statements — such as if let, switch, or if/else — to create conditional views:

ViewBuilder uses the method below for handling Conditional Content.

SwiftUI uses view builders in many places. All container views like stacks and grids, as well as modifiers like background and overlay, take a view builder closure to construct their subviews. Furthermore, the body property of each view is implicitly marked with ViewBuilder, as is the body(content:) method of view modifiers.

References:

https://www.objc.io/books/thinking-in-swiftui/

Github: https://github.com/abdahad1996/SwiftUI_Bootcamp/blob/main/SwiftUI_Bootcamp/SwiftUI_Bootcamp/ViewModifier/ViewModifier.swift

--

--

abdul ahad
abdul ahad

Written by abdul ahad

A software developer dreaming to reach the top and also passionate about sports and language learning

No responses yet