Toolbars and Sheets
Introduction
In this article, you will learn:
- What a toolbar in Swift is
- How to create a toolbar
- What a
ToolbarItem
is and how to add them to a toolbar - To provide a
ToolbarItem
a specific placement - What is a Sheet
- How to present a Sheet
- How to present a toolbar inside a sheet
Let’s begin by creating a project that will showcase the capabilities of toolbars and sheets. Your final project will resemble the following video.
Creating the project
To begin, open up Xcode. You should get a window that resembles the image below.
In the center of the Xcode window, you will see Create a new Xcode project. Go ahead and click on this.
Next, you should see project templates. App should already be selected; if not, go ahead and click that. At the bottom right, click on Next. You will now insert some information regarding the application.
- Product Name: ToolbarProject
- Team:
None
is acceptable here; If you have a team identifier, feel free to use it - Organization Identifier: This is usually your reverse domain; for now,
com.YourName
is appropriate - Bundle Identifier: It should be automatically filled provided your Organization Identifier + Product Name.
- Interface: Be sure to select
SwiftUI
- Life Cycle:
SwiftUI App
- Language:
Swift
Use Core Data
is OFFInclude Tests
is OFF
Now select where you would like to save the project. Do not select Create Git repository on my mac
. Git is a popular tool used for version control. If you do want to use Git for version control, select the option and learn more about Git here.
Once you select a location, click on Create. Your project should look similar to the image below.
Fantastic, you’re now ready to start building toolbars and displaying sheets in your project!
What is a toolbar?
SwiftUI’s toolbar modifier allows for placement of views along the top or bottom space of a view. For a toolbar to work properly, it must be embedded in a NavigationView
.
Here is a view that contains a toolbar with two buttons at the top of the view.
Create a toolbar
To properly attach a toolbar, first create a NavigationView
. Within it, embed Text("Hello World")
.
import SwiftUIstruct ContentView: View {var body: some View {NavigationView {Text("Hello World")}}}
According to the Apple docs, a toolbar wraps views just like a VStack
or NavigationView
. A toolbar is written as:
NavigationView {Text("Hello World").toolbar {// Views go here}}
Let’s use the same methodology to create a toolbar in the project. Also, change Text("Hello World")
to Text("Initial View")
.
ContentView.swift
import SwiftUIstruct ContentView: View {var body: some View {NavigationView {Text("Initial View").toolbar {}}}}
Great work! You created your first toolbar. Your view should match the image here.
The view looks the exact same!? That’s because the toolbar is by default a transparent container.
Let’s add some buttons to the toolbar to make it useful. You can use a ToolbarItem
to display a button on the toolbar. Let’s take a look at ToolbarItem
.
What is a ToolbarItem
?
According to the Apple docs, SwiftUI’s ToolbarItem
represents a container for placing one item on a toolbar. If you want more than one item, you will have to use multiple ToolbarItem
s. ToolbarItem
s usually contain a Button
, Text
, or Image
. A ToolbarItem
is written as so:
NavigationView {Text("Hello World").toolbar {ToolbarItem {// Items goes here}}}
Let’s use the same methodology to create a ToolbarItem
in the project. Inside the ToolbarItem
, place a Button
using the Button(action:, label:)
constructor with an empty action and Image(systemName: "gear")
for the label.
ContentView.swift
import SwiftUIstruct ContentView: View {var body: some View {NavigationView {Text("Initial View").toolbar {ToolbarItem {Button(action: {// Action goes here}, label: {Image(systemName: "gear")})}}}}}
Fantastic! You added a ToolbarItem
to your toolbar. The ToolbarItem
contains a button. Your preview should match the one here.
But, what if you want to put the button on the other side of the toolbar? You can do so by providing a specific placement for your item. Let’s see how it’s done.
ToolbarItem
placement
A ToolbarItem
can be given a specific placement onto the toolbar. The placement is determined by the optional placement
parameter for ToolbarItem
which takes in a value of type ToolbarItemPlacement
. If there is no placement given, it will default to the top right corner. You can place a ToolbarItem
in the top left corner by passing in .navigationBarLeading
with the given code:
NavigationView {.toolbar {ToolbarItem(placement: .navigationBarLeading) {// Button goes here}}}
Since Xcode can safely assume you will place an instance of ToolbarItemPlacement
inside the placement
argument using type inference, you can type .
in the argument and the full list of ToolbarItemPlacement
options will display. Here is an example of that working (disregard the error as it will disappear on selection):
In your project, assign your current ToolbarItem
a placement of .navigationBarLeading
.
ContentView.swift
import SwiftUIstruct ContentView: View {var body: some View {NavigationView {Text("Initial View").toolbar {ToolbarItem(placement: .navigationBarLeading) {Button(action: {}, label {Image(systemName: "gear")})}}}}}
Great! You moved your gear button to the top left corner of the view using the placement: ToolbarItemPlacement
input parameter.
Your preview should match the one here.
Now, let’s present a new view on the Button
tap.
What is a sheet?
SwiftUI sheets are used to present a new view over an existing one. Think of this as a stack of papers. You can have multiple sheets on top of one another, and the middle one can be accessed by removing the ones above it.
Here is an example of a sheet being displayed.
How to present a sheet
A sheet, like the one above, is presented using a binding of a Bool
. As the boolean changes, the binding will change the view. If the Bool
is true
, the sheet will be presented. When it is set to false
, the sheet will dismiss. The Bool
is usually stored in the structure as an @State
variable to be able to modify the view as it changes.
A sheet can be presented using the following:
@State var isPresenting: Bool = falseNavigationView {.toolbar {ToolbarItem(placement: .navigationBarLeading) {Button("Some Button") {isPresenting = true}}}.sheet(isPresented: $isPresenting) {// View to display goes here}}
The sheet takes in isPresented: $isPresenting
which is the binding Bool
for the view to keep track of. When the isPresenting
is set to true
on the button tap, the sheet will display the view inside the sheet.
Let’s add a sheet to your project. Inside the sheet, display a NavigationView
. Inside the NavigationView
, display a Text("Settings Page")
. Don’t forget to set the isPresenting
property to true
when the button is tapped!
ContentView.swift
import SwiftUIstruct ContentView: View {var body: some View {NavigationView {Text("Initial View").toolbar {ToolbarItem(placement: .navigationBarLeading) {Button(action: {}, label {Image(systemName: "gear")})}}.sheet(isPresented: $isPresenting) {NavigationView {Text("Settings Page")}}}}}
Great work! You added a sheet
that contains a Text("Settings Page")
. You are able to see the sheet when the Button
is tapped because isPresenting
is set to true
. You can also dismiss the sheet by sliding the view downwards.
Your preview should match the one here.
Toolbar within a sheet
But, what if you wanted to present a toolbar inside the sheet that you are displaying? You would implement the same strategy as you’ve done previously by adding a NavigationView
inside the sheet
and then add a toolbar
inside the NavigationView
.
In your project, since there is already a NavigationView
inside the sheet, attach a toolbar that contains a ToolbarItem
. Place a Button("Save") {}
inside the ToolbarItem
with no specified placement.
ContentView.swift
import SwiftUIstruct ContentView: View {var body: some View {NavigationView {Text("Initial View").toolbar {ToolbarItem(placement: .navigationBarLeading) {Button(action: {}, label {Image(systemName: "gear")})}}.sheet(isPresented: $isPresenting) {NavigationView {Text("Settings Page").toolbar {ToolbarItem {Button("Save") {}}}}}}}}
Fantastic! The toolbar displays a sheet that contains a toolbar. The second toolbar contains a button titled "Save"
that doesn’t have an action, yet.
Your preview should match the one here.
Conclusion & review
Great work! In this article, you’ve covered toolbars and sheets. You created a miniature project that simulates an application that displays a settings page from a button tap on the toolbar.
Here’s a recap:
- A toolbar allows for placement of buttons along the top or bottom space of a view
- You create a toolbar using the following code snippet:
NavigationView {Text("Hello World").toolbar {// Views go here}}
- A
ToolbarItem
represents a container for placing one item on a toolbar - A
ToolbarItem
is created using the following code snippet:
NavigationView {Text("Hello World").toolbar {ToolbarItem {Button("Toolbar Item Button")}}}
- A
ToolbarItem
placement is indicated using theplacement: ToolbarItemPlacement
parameter. The list of options are available on Xcode or on the Apple docs. - A sheet is used to present a new view over an existing one.
- A sheet is presented using the following code snippet:
@State var isPresenting: Bool = falseNavigationView {Text("Hello World").toolbar { /* Toolbar */ }.sheet(isPresented: $isPresenting) {// Views go here}}
- A toolbar can be presented inside a sheet using the following code snippet:
@State var isPresenting: Bool = falseNavigationView {Text("Hello World").toolbar { /* Toolbar */ }.sheet(isPresented: $isPresenting) {NavigationView {Text("Settings Page").toolbar {ToolbarItem {Button("Some Button")}}}}}
Author
'The Codecademy Team, composed of experienced educators and tech experts, is dedicated to making tech skills accessible to all. We empower learners worldwide with expert-reviewed content that develops and enhances the technical skills needed to advance and succeed in their careers.'
Meet the full team