I’m going to walk through the steps to create a default view in a
NavigationView in a brand new project.
The finished GitHub project can be found here.
1. Create a Single View App
Create a new XCode project using SwiftUI.
2. In ContentView.swift, add a NavigationView
ContentView.swift looks like this:
To add a NavigationView that looks like a list, we first need to embed the
Text in a
List. Embedding in a
List can be done by
CMD + Click on
Text and choosing Embed in List from the menu.
You should then get the code sample below.
Now, put the list inside the
ContentView should now have the following code:
If using the Live Preview in Xcode, then the preview should look like the picture below.
Let’s also make the list different on each row. Change the string in the text to say “Navigation Link (item)” and make the list range 1 to 5 instead of 0 to 5.
This is what the code should look like.
Here is what the preview will look like
3. Add a NavigationLink
Text needs to be inside a
NavigationLink in order to navigate to a different view. We will use
NavigationLink(destination: Destination, tag: Hashable, selection: Binding<Hashable?>, label: () -> Label).
Let’s break this down a bit before implementing it.
Viewto present when the link is selected
taga value that is of type
Hashable1 to distinguish between which link is selected
selectiona variable that is an optional
Hashabletype that will change values to the tag
labela closure that returns a
Viewwhich is what the user will see and be able to click on.
Now that all the parts are explained let’s implement the
Once it’s implemented, you should get an error that says
Use of unresolved identifier '$selectedView'. This error is expected since we do not have a Binding variable called
selectedView in our code. Let’s add it to the
@State private var selectedView: Int? = 0 before declaring
body. The error should go away now. When declaring
selectedView, the type needs to be optional since
NavigationLink wants an optional Hashable type.
As of right now, running the app, it will look like no default view is given. This is because there is no
NavigationLink with a tag of 0. If
selectedView is assigned a tag that doesn’t exist, then the view will be the list of NavigationLinks.
If you change the initial value of
selectedView to 1, then it will open to the destination of
NavigationLink that has a tag of 1.
Basics are done!
Now the basic tutorial is finished of how to achieve this. I’m going to continue in the next section on how to improve the UX because on iOS this is not excellent behavior, but on iPadOS when in landscape, this behavior is excellent!
Bettering the UX
On iPhones, you don’t usually want the total view to be taken over. You usually want the user to decide where to navigate. On iPads in landscape, the screen is so big that having a view selected is okay since the navigation links are always shown. This can be achieved by using
onAppear() and figuring out which device is being used.
First, we need to add
onAppear() to the
List. Then, we need to get the device type.
Now, we need to do something based on each device. We can get the device type by using
.model. We can then use a simple if statement to determine if it’s an iPhone or an iPad and set the selection based on that. We also need to check the orientation of the iPad.
That would be it! The view will change on device and orientation.
Here’s a gif of the iPad:
Here’s a gif of the iPhone’s implementation: