Programmatic Navigation & Deep Linking
Drive navigation from code, not just taps. Learn NavigationStack with a path binding, navigationDestination(for:) , pushing and popping in code, type-safe routes with an enum , and deep linking with onOpenURL .
Learn Programmatic Navigation & Deep Linking in our free Swift course — a beginner-friendly interactive lesson with worked examples, a practice exercise and…
Part of the free Swift course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ Basic NavigationLink
A plain NavigationLink pushes a destination when the user taps it. That is fine for simple menus but gives you no control from code.
2️⃣ Programmatic Push and Pop
Bind a path to the NavigationStack . Append values to push, empty it to pop to root — all from your own code, not taps.
3️⃣ Type-Safe Routes with an Enum
A Hashable enum names every valid destination. A switch in navigationDestination(for:) forces you to handle each case.
Your turn. Fill in the path binding and the method that pushes a value.
4️⃣ Deep Linking with onOpenURL
onOpenURL fires when the app opens from a URL. Parse it into a route value and append it to the path to jump straight to the right screen.
📋 Quick Reference
Build a Hashable route enum, bind it to a NavigationStack, and push a profile screen from a button.
Practice quiz
Which container replaced NavigationView for stack navigation in modern SwiftUI?
- NavigationStack
- NavigationView
- TabView
- ScrollView
Answer: NavigationStack. NavigationStack is the modern push/pop container introduced in iOS 16.
What does binding a path to a NavigationStack let you do?
- Add tabs
- Style the bar
- Drive navigation programmatically by editing the path array
- Disable navigation
Answer: Drive navigation programmatically by editing the path array. A path binding holds the navigation stack so you can push and pop by mutating the array.
Which modifier registers what view to show for a given value type?
- onAppear
- navigationDestination(for:)
- sheet(item:)
- navigationTitle
Answer: navigationDestination(for:). navigationDestination(for:) maps a value type to the destination view it should present.
To pop to the root of a NavigationStack programmatically, you...
- Call dismiss()
- Remove the modifier
- Restart the app
- Set the path to an empty collection
Answer: Set the path to an empty collection. Emptying the path collection pops every pushed view back to the root.
How do you push a new screen programmatically with a path binding?
- Append a value to the path
- Toggle a Bool
- Use a segue
- Call push()
Answer: Append a value to the path. Appending a value to the bound path pushes its matching navigationDestination view.
Why use an enum for type-safe routes?
- It avoids imports
- It enumerates all valid destinations the compiler can check
- It is required by SwiftUI
- It is faster
Answer: It enumerates all valid destinations the compiler can check. An enum lists every valid route so the compiler catches typos and missing cases.
Which modifier handles an incoming deep-link URL?
- onTapGesture
- onChange
- onReceive
- onOpenURL
Answer: onOpenURL. onOpenURL(perform:) fires when the app is opened via a URL, letting you parse and route.
After parsing a deep-link URL, how do you navigate to that screen?
- Show an alert
- Ignore it
- Append the parsed route value to the navigation path
- Reload the app
Answer: Append the parsed route value to the navigation path. You translate the URL into a route value and append it to the path to navigate there.
How does NavigationLink(value:) differ from the basic NavigationLink(destination:)?
- It opens a sheet
- It pushes a value resolved by navigationDestination instead of an inline view
- It does nothing
- It is deprecated
Answer: It pushes a value resolved by navigationDestination instead of an inline view. NavigationLink(value:) sends a value that navigationDestination(for:) turns into a screen.
For routes to drive a path and be diffable, the route type should be...
- Hashable
- A class
- Optional
- Sendable only
Answer: Hashable. Path values must be Hashable so the stack can store and compare them.