Navigation in iOS 16 SwiftUI | NavigationStack

Moussa Hellal
4 min readMay 21, 2023

Since Navigation had a huge shift in iOS 16, and the old way of navigation has faced deprecation.

It is time to get into Navigation and understand its ins and outs. I plan to write multiple articles on the subject of Navigation in the upcoming future but for now let’s start out with the basics of NavigationStack.

The New Navigation in iOS 16, has few things to take in mind:


this component is responsible for the root view and presenting (navigating) to other views on top it.


data container that maintains a record of the content being shown on various screens or views.

navigationDestination(for: destination: )

This function is in charge of connecting a destination view with a certain data type that it displays, enabling its usage within a navigation stack.

Let’s get into it:

Our project that we are going to use is an app that lists few drinks and a Drink Detail view.

We have two views:

  • DrinkyView (left Side) — Contains the list of drinks.
  • DrinkyDetailView(right side) — Contains the drink details.

Project Link: , download and open the before folder to follow up with me it has both views with no navigation.

Now let’s open up the before folder. If you want you can also check after folder which has the final result of this article and you can continue to understand how we implemented the navigation with me here.

First thing we need to add the navigation logic to our DrinkyView.

  1. Open the file DrinkyView
  2. As we talked earlier about NavigationPath and how it will hold the data for the views. In our example it will hold our Drink object as an array.

Add Our viewModel Object that holds our mock data, and our path state

@State private var path: [Drink] = []
@StateObject private var viewModel = DrinkViewModel()

3 . Let’s wrap our ScrollView inside the NavigationStack(path: $path)with our path as a binded parameter so the NavigationStack here knows exactly when the path will be changed.

The role here of NavigationStack is wrapping our root view and whenever a new view is presented it will be on top of the previous view, think of it as a deck of cards.

4. Once the user click on our button which holds our container view for the Image, Drink name and short description we need to move to next screen by appending our selected drink object to the path.


5. Finally we simply add our modifier for title and navigationDestination

.navigationTitle("Drinky") // used for the View title
.navigationDestination(for Drink.self) { drink in
DrinkyViewDetails(drink: drink)

The true magic resides here where our navigation will move to details screen with the selected object that we have appended to our path object.

6. Good thing! you don’t need to add anything to our DrinkyViewDetailsas it only accepts a drink object as a parameter and present it, all navigation logic is handled within our root view DrinkyView.

That’s it just run the app and everything will work, just like magic!

If you don’t want to write any code just download the Github project and open up the after folder.

Project Link:

As you have observed here the true power of the NavigationStack and how it can be used with our custom defined object through our navigation path.

I appreciate you choosing to spend some of your day with me. I hope that my piece was informative and helpful to you.

Farewell, keep growing and learning. See you in the next one. ✌️

Make sure to follow me on Twitter to keep receiving the newest articles: