Value-Based NavigationLink

NavigationLink with values separates "what to navigate to" from "how to display it." Here's how it works.
Follow along with the code: iOS-Practice on GitHub
The Old Way (Deprecated)
// iOS 15 and earlier
NavigationLink(destination: UserDetailView(user: user)) {
Text(user.name)
}
Problems:
- Destination view created immediately
- Hard to share navigation logic
- No programmatic navigation
The New Way
// iOS 16+
NavigationLink(value: user) {
Text(user.name)
}
The destination is defined separately:
.navigationDestination(for: User.self) { user in
UserDetailView(user: user)
}
Complete Example
struct MasterView: View {
let users: [User]
var body: some View {
List(users) { user in
NavigationLink(value: user) {
HStack {
Image(systemName: user.avatarURL)
.font(.title)
VStack(alignment: .leading) {
Text(user.name).font(.headline)
Text(user.company).font(.caption)
}
}
}
}
.navigationTitle("Users")
.navigationDestination(for: User.self) { user in
UserDetailView(user: user)
}
}
}
Multiple Destinations
Handle different types with multiple modifiers:
.navigationDestination(for: User.self) { user in
UserDetailView(user: user)
}
.navigationDestination(for: Post.self) { post in
PostDetailView(post: post)
}
.navigationDestination(for: Settings.self) { _ in
SettingsView()
}
Programmatic Navigation
Control navigation with NavigationPath:
struct ContentView: View {
@State private var path = NavigationPath()
var body: some View {
NavigationStack(path: $path) {
Button("Go to User") {
path.append(someUser)
}
.navigationDestination(for: User.self) { user in
UserDetailView(user: user)
}
}
}
func navigateToUser(_ user: User) {
path.append(user)
}
func popToRoot() {
path.removeLast(path.count)
}
}
Hashable Requirement
Your model must conform to Hashable:
struct User: Identifiable, Hashable {
let id: Int
let name: String
let email: String
// Hashable is auto-synthesized for structs with Hashable properties
}
Benefits
- Lazy destination creation - Views created only when navigated
- Type safety - Compiler verifies navigation types
- Centralized logic - One place defines all destinations
- Deep linking - Easy to restore navigation state from URL
Interview Tip
This is the modern SwiftUI navigation pattern. Discuss how it enables programmatic navigation and deep linking.