Understanding SwiftUI Navigation Stack
How NavigationStack and NavigationPath simplify app navigation in SwiftUI.
Navigation in SwiftUI – The Modern Way
Since iOS 16, SwiftUI offers NavigationStack as a much more flexible alternative to NavigationView. Here's how to work with it.
NavigationStack Basics
The simplest approach:
NavigationStack {
List(items) { item in
NavigationLink(item.name, value: item)
}
.navigationDestination(for: Item.self) { item in
DetailView(item: item)
}
}The big advantage over the old NavigationLink(destination:): Navigation is data-driven instead of view-driven.
NavigationPath for Programmatic Navigation
With NavigationPath you can programmatically control the navigation stack:
@State private var path = NavigationPath()
NavigationStack(path: $path) {
Button("Go to Detail") {
path.append(myItem)
}
.navigationDestination(for: Item.self) { item in
DetailView(item: item)
}
}
This enables:
- Deep Linking – Navigate directly to a specific screen
- Pop to Root – Go back to the start with
path.removeLast(path.count) - State Restoration – NavigationPath is Codable
Multiple Destination Types
You can register different data types as navigation destinations:
NavigationStack(path: $path) {
ContentView()
.navigationDestination(for: User.self) { user in
UserView(user: user)
}
.navigationDestination(for: Settings.self) { settings in
SettingsView(settings: settings)
}
}Conclusion
NavigationStack is the right approach for new SwiftUI projects. Data-driven navigation makes code cleaner and enables features like deep linking without much effort.