SwiftUI Navigation: NavigationStack Patterns
NavigationStack replaced NavigationView in iOS 16. Here are the patterns that work for real apps.
Key Insights
- NavigationStack with NavigationPath gives you programmatic control over the navigation stack
- Type-safe navigation destinations replace stringly-typed approaches
- Deep linking becomes trivial when navigation state is data-driven
Basic NavigationStack
struct ContentView: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
List(items) { item in
NavigationLink(value: item) {
Text(item.title)
}
}
.navigationDestination(for: Item.self) { item in
DetailView(item: item)
}
}
}
}
Programmatic Navigation
// Push a view
path.append(someItem)
// Pop to root
path = NavigationPath()
// Pop one level
path.removeLast()
Deep Linking
Since the path is just data, restoring state from a URL is straightforward:
func handle(url: URL) {
let components = url.pathComponents
path = NavigationPath()
for component in components {
if let item = resolveItem(component) {
path.append(item)
}
}
}