Set data in prepareForSegue with navigation controller
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
When prepare(for:sender:) involves a navigation controller, the main trick is understanding what segue.destination actually is. If the destination scene is embedded in a UINavigationController, you do not set data on the navigation controller itself. You unwrap its visible or top view controller and pass data to that real content controller.
Start with the normal prepare(for:sender:) pattern
For a direct segue to a detail controller, the code is simple:
That works when the destination is the actual DetailViewController.
Embedded navigation controllers change the destination type
If the storyboard segue goes to a navigation controller whose root view controller is DetailViewController, then this cast fails:
The real destination is a UINavigationController, so you need to unwrap it:
This is a very common pattern for modal flows where the presented screen has its own navigation stack.
Choose topViewController or visibleViewController deliberately
In many cases, topViewController is enough because the navigation controller has not started navigating yet. visibleViewController can also work, but the important part is to reach the actual screen controller that owns the data property.
For a root controller that is embedded at presentation time, either of these is often fine:
- '
nav.topViewController' - '
nav.visibleViewController'
Use the one that matches your storyboard structure and make the cast explicit.
Keep segue identifiers explicit
As screens grow, prepare(for:sender:) becomes hard to reason about if every segue uses untyped branching. Naming the segue and checking its identifier keeps the method predictable:
That structure scales better than guessing destination types without checking which segue fired.
Push segues usually do not need navigation unwrapping
If you are pushing onto an existing navigation stack, segue.destination is often already the destination content controller, not a new UINavigationController.
So the navigation-controller unwrap is usually needed when:
- presenting a modal flow embedded in a nav controller
- using a storyboard scene whose initial view controller is a nav controller
It is usually not needed for a standard push from one content controller to another.
Prefer direct property assignment over reaching through later
prepare(for:sender:) is the right time to set simple destination properties such as IDs, selected models, or flags. It keeps the data handoff near the navigation event instead of scattering it through lifecycle methods later.
If the dependency graph becomes complicated, use dependency injection patterns or coordinators, but for straightforward storyboard flows, direct property assignment is still fine.
Common Pitfalls
- Casting
segue.destinationdirectly to the content controller when it is actually aUINavigationController. - Setting data on the navigation controller instead of the child view controller that needs it.
- Forgetting to check the segue identifier before unwrapping destination types.
- Using navigation-controller unwrapping for ordinary push segues where it is not needed.
- Assuming
prepare(for:sender:)runs after the destination has already loaded all of its UI state.
Summary
- '
prepare(for:sender:)passes data to the destination before the transition completes.' - If the destination scene is embedded in a
UINavigationController, unwrap it first. - Set data on the child content controller, usually via
topViewControllerorvisibleViewController. - Use segue identifiers so destination-type logic stays explicit.
- Standard push segues often do not require navigation-controller unwrapping.
Related reading
- Set deployment target for CocoaPods's pod
- Set EditText cursor color
- Set Focus on EditText
- Set icon for Android application
- Set ImageView width and height programmatically?
- Set ImageView width and height programmatically?
- set initial viewcontroller in appdelegate - swift
- Set inputType for an EditText Programmatically?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.