SwiftUI NavigationStack: Revolution of nested navigation with SwiftUI

If you are really struggling with multi level nested navigation with SwiftUI’s new NavigationStack and NavigationPath then this article is a huge plus point for you because I will discuss it deeply with a perfect sample project on GitHub

Md Yamin
4 min readMay 11, 2023
Photo by Holly Stratton on Unsplash

Lets jump into the coding with less talking 😊. SwiftUI’s new navigation framework uses NavigationStack as a root view component and NavigationPath gives us such more powerful control over the whole navigation that was absent in the previous NavigationView component.

It is my suggestion that be patient and fully read the article, I can ensure you that you will not find any details description like this online. Surely 99% of your problems with new NavigationStack will be resolved.

At first we will see the normal nested navigation using NavigationStack and NavigationLink. Don’t worry we will discuss the complex one later in this article. In the following ContentView.swift file, if you click the NavigationLink it will show the first DetailsView.swift. Since every NavigationStack has its own single stack, it will push the first DetailsView onto that stack.

Then when you click the button in the DetailsView to show the second DetailsView another copy of DetailsView will be pushed onto the first item of the NavigationStack’s stack. Similarly you can go clicking more and more into multiple nested DetailsView as you wish. You will look that here I used one single DetailsView.swift file for simplicity but you can use different files. Look at the following output:

Multi level nested navigation

Now the complex (not too much😉) part of NavigationStack is using NavigationPath we can handle the navigation of NavigationStack. For example I want to go back to the first DetailView from the fourth DetailsView skipping all the middle views. In this case NavigationPath shows it’s ✨ magic ✨ . We can store any Hashable data in NavigationPath and for every data type we have to set a navigationDestination using the function navigationDestination(for: ) so that every time we push a data onto the NavigationPath stack and NavigationStack navigate the View to the corresponding destination details view with that data.

This is called the new data driven navigation approach initiated by SwiftUI

See the following ContentView.swift file. There are two types of data named FastFood and Cloth. We set details destination for both data but we also defined another destination for data type String because we will navigate into two different list View dynamically depending on the Tag of those Views. See FoodItemListView.tag directs to FoodItemListView and ClothItemListView.tag directs us to ClothItemListView.

Very important !!! Remember when you are using NavigationPath with NavigationStack, each navigation from first View should be done with NavigationPath. Don’t do any navigation without NavigationPath. Otherwise a View that was navigated to without NavigationPath can become appear again and again like a loop!!!

Did you notice that in the first case we did not use any NavigationLink? Only pushing data to the NavigationPath like: path.append(FoodItemListView.tag) directs us to the corresponding destinations 😍.

In the second case we used NavigationLink like NavigationLink(value: ClothItemListView.tag) , so you can push any data to the NavigationLink and the data will be automatically pushed or appended to the NavigationPath by NavigationLink and your View will be directed to the corresponding destination View by NavigationStack according to your declaration of navigationDestination(for: ) function.

Every FoodItemDetailsView and ClothItemDetailsView contains related foods and cloths. You can go further more details views clicking those food and cloth items. Now if you want to go back to the first list view skipping all middle details views, how can you do that? Just remove all corresponding data for those middle views from the path stack keeping only the first one, NavigationStack will automatically direct you to the first View. Similarly you can go back to the second, third whatever View you want like below:

Button(action: {
while path.count > 1 { // For going back to the first view 😊
path.removeLast()
}
})

Button(action: {
while path.count > 3 { // For going back to the third view 😊
path.removeLast()
}
})

Now see the output:

Coming back to to a distinct view skipping middle views

So, that’s it for today 😊 you can download the full sample little project from this GitHub link. If you find anything wrong or if you have any questions just comment below, I will try to answer as soon as possible. Don’t forget to clap it and star the sample project 🥰

--

--

Md Yamin

A self-directed and motivated Software Engineer with over 5 years of comprehensive hands-on experience in iOS and Android applications development.