Leave a rating/review
iOS 16 introduced a new way to navigate with NavigationStack. You may be thinking “wait, NavigationView is essentially a stack, so what’s the difference?”. That’s a great question.
Let’s look at the differences between NavigationView and NavigationStack
NavigationLink is still central to navigation around your app. In iOS 16 however, a new initializer was introduced that takes in an object that is Hashable, along with the view that represents the link on screen.
This means there is no destination anymore! How does your app know where to go?
iOS 16 introduced a new modifier called navigationDestination which takes in a Type, and a closure that take in an instance of that type, returning the view to which your app will navigate.
Up to this point, it looks like a lot of reshuffling of where things happen. But separating out the destination like this allows you to handle having multiple types of NavigationLinks in your NavigationStack by attaching multiple navigationDestination modifiers for each type.
There is one more long awaited piece of functionality that NavigationStack provides - the ability to programmatically navigate via a path. NavigationStack has an initializer that takes in a binding to a NavigationPath object, or a collection of Hashable objects. This lets you specify exactly where you want the app to be in the NavigationStack by populating the path.
This allows for really easy deep linking - immediately loading up a page on startup - or popping back to the top of the stack immediately by emptying the path.
Let’s take a look at some of these features in a demo.
This starter project is the same as the starter project of the last episode. This time however, you’ll use NavigationStack.
The goal here is to connect the ContentView
Open
ContentView.swift
with the DetailView
Open
DetailView.swift
Open
ContentView.swift
Now, when you tap on a row in ContentView, you would probably expect to go to a detail view of the artwork.
So, let’s connect these two views.
- You need to embed this list in a
NavigationStack.
NavigationStack {
List(artworks) { artwork in ...}
}
This gives you the root of a new navigation stack.
You can now access all the navigation things you did with NavigationView, like the navigation bar title.
List(artworks, id: \.self) { artwork in
}
.navigationTitle("Artworks")
Remember that this modifies List, not NavigationStack.
NavigationStack still requires NavigationLinks to work. This is the key to adding views to the navigation stack.
- Start typing
NavigationLinkand let autocomplete show you the possible initializers. - Pick the one that takes a value and a label.
- You can use the text that’s already there for a label.
- For the value, use the closure’s
artworkobject
List(artworks) { artwork in
NavigationLink(value: artwork) {
Text(artwork.title)
}
}
Now you need to specify a destination. Below the .navigationBarTitle modifier, add one for navigationDestination
- Use Artwork.self as the type
- For the destination, make an instance of whatever view you want to navigate to. Like, the DetailView!
- And you can just pass in the artwork associated with this item in the List.
.navigationDestination(for: Artwork.self) { artwork in
DetailView(artwork: artwork)
}
Start up a live preview to test it out.
Live Preview
And there’s the detail you’re looking for!
Split View
In the last episode, using NavigationView on the iPad, you had to add a DetailView to the NavigationView so something would show on the screen at launch. Is this still needed?
Switch to the 12.9 inch iPad Pro and reload the preview canvas. Hey, it’s your list of artwork, so you don’t need an extra DetailView. Great!