Just like SwiftUI’s ViewBuilder, ToolbarContentBuilder is used to put together dynamic ui content for toolbars
Intro
In SwiftUI, the Toolbar component is essential for adding UI elements like buttons, menus, and controls to the navigation bar or bottom bar of our app. However, as our apps grows and becomes more complex, the toolbar code can become cluttered and difficult to manage. This is where ToolbarContentBuilder
comes to the rescue. The ToolbarContentBuilder
attribute provides us with a clean way to refactor our toolbar code and keep it organized. The goal of this article is for us to explore how to use ToolbarContentBuilder to streamline our toolbar logic implementations, but first let’s take a look at the problem.
The Challenge with Complex Toolbars
As our SwiftUI app evolves, we might find yourself needing to add multiple buttons, menus, or other UI elements to the toolbar. Without proper organization, the toolbar code can quickly become hard to read, maintain, and extend. This is especially true when we are dealing with conditional or dynamic toolbar content.
Consider the following scenario: we have a view that needs to display different toolbar buttons depending on the user’s authentication status. In traditional SwiftUI code, we might end up with something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var body: some View {
NavigationStack {
VStack {
}
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
if isAuthenticated {
Button("Profile") {
// Show user profile
}
}
}
ToolbarItem(placement: .navigationBarTrailing) {
Button("Settings") {
// Show app settings
}
}
}
}
}
As you can see, the code becomes cluttered with conditional statements and nested blocks. Additionally, if we need to add more toolbar items or refactor existing ones, the code can become even more convoluted. And if you’re like me, who likes to prioritize a streamlined view’s body for improved readability, this clearly presents a noteworthy concern.
Introducing ToolbarContentBuilder
The ToolbarContentBuilder
is a declarative way to build our toolbar content in SwiftUI. It simplifies the process of creating complex toolbars by allowing us to refactor our toolbarItems into functions or computed properties just by simply annotating them with the @ToolbarContentBuilder
attribute. Think of it as viewbuilder for composing dynamic content views for our toolbars.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@ToolbarContentBuilder
private var cancelToolbarButton: some ToolbarContent {
ToolbarItem(placement: .navigationBarLeading) {
Button("Cancel") {
// canceling...
}
}
}
@ToolbarContentBuilder
private var downloadToolbarButton: some ToolbarContent {
ToolbarItem(placement: .navigationBarTrailing) {
Button("Download") {
// downloading...
}
}
}
@ToolbarContentBuilder
private var dismissKeyboardToolbarButton: some ToolbarContent {
ToolbarItem(placement: .keyboard) {
Button("Dismiss") {
// dismissing keyboard here
}
}
}
Now inside of our toolbar modifier, we can easily compose the toolbar content like this:
1
2
3
4
5
6
7
8
9
10
11
12
var body: some View {
NavigationStack {
VStack {
}
.toolbar {
cancelToolbarButton
downloadToolbarButton
dismissKeyboardToolbarButton
}
}
}
Bye
Hopefully you found some value in this neat little toolbar refactoring approach, thanks for reading.