SwiftUI simple viewBuilder practical usage guide
How to use @ViewBuilder in your SwiftUI projects
Fundamentals
@ViewBuilder
is a function builder in SwiftUI that allows you to create views by composing smaller views. It is typically used to create custom views that can build and combine other views to create their own complex layout.
Apple defines it in its documentation as : A custom parameter attribute that constructs views from closures.
Many of the built-in views in SwiftUI that we use all the time, implements@ViewBuilder
to compose their subviews and layouts. For example, the VStack
view, which arranges its subviews in a vertical stack, uses @ViewBuilder
to build its layout from the subviews it is given.
Actually, you can open any of your SwiftUI structs that conforms to View protocol, it necessary has a body. If you jump to its definition you will find that body is actually returning a @ViewBuilder
, we just tend not to write explicitly and let SwiftUI handles it, here is an example :
Usage
@ViewBuilder
is an important part of the SwiftUI framework because it allows you to create custom views that can build and combine other views to create complex layouts. This makes it much easier to create and reuse view hierarchies in your app, which can help to improve code reuse and maintainability.
Constructing View
In this example, the CustomView
struct accepts a closure containing a view hierarchy as a parameter in its initializer. The closure is marked with the @ViewBuilder
attribute, which allows you to write the closure in a more concise and declarative style, without having to explicitly wrap each view in a closure.
To use this CustomView
, you would create an instance of it and provide it with a closure containing the views you want to include in the view hierarchy.
Wrapping Views
In this example, the WrapperView
struct takes a generic Content
parameter that specifies the type of view that it will wrap. The content
parameter of the initializer is marked with the @ViewBuilder
attribute, which allows you to pass in a closure containing the view you want to wrap.
To use this WrapperView
, you would create an instance of it and provide it with a closure containing the view you want to wrap and applying that padding, background, cornerRadius etc.. modifiers to it, without needing to write them every time on different views, just wrap them !
Custom Modifiers
You can use @ViewBuilder
to create custom view modifiers that build and combine other views to create their layout. Here is an example of how you might use @ViewBuilder
to create a custom view modifier that adds a border and a drop shadow to the view it is applied to:
In this example, the ShadowBorderModifier
struct defines a custom view modifier that adds a black border and a drop shadow to the view it is applied to. The body
method of the ShadowBorderModifier
is marked with the @ViewBuilder
attribute, which allows you to build and combine views inside the method body.
To use this ShadowBorderModifier
, you would apply it to a view using the .modifier()
method. Or in my case, i made an extension of View
that returns a ModifierContent
as the ShadowBorderModifier.
Tips
Here are a few tips and things to consider when using @ViewBuilder
in your code:
- When using
@ViewBuilder
, be sure to mark the closure, initializer, or method that contains the view hierarchy with the@ViewBuilder
attribute. This will allow you to use@ViewBuilder
to build and combine views inside that closure, initializer, or method. - If the closure, initializer, or method that contains the view hierarchy is marked with the
@escaping
attribute, be sure to include that attribute when you apply the@ViewBuilder
attribute. This is necessary because the view hierarchy will be calculated asynchronously, and the closure may be called at any time after the initializer has finished. - When using
@ViewBuilder
to build and combine views, be sure to use the correct return type for the closure, initializer, or method that contains the view hierarchy. This should typically besome View
, which indicates that the view hierarchy can contain multiple views of any type.
Thanks for reading.