Completion block for popViewController
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
UINavigationController.popViewController does not include a built in completion handler, which makes post pop work awkward when you need to chain logic. This is common when you want to refresh previous screens, fire analytics after transition, or start another animation only after navigation finishes. The solution is to attach completion behavior to the navigation transition lifecycle.
Why popViewController Has No Completion Parameter
The pop call starts a transition and returns immediately. Animation timing is managed by UIKit transition internals, so code placed right after pop can run too early. If you need sequencing, use transition coordinator callbacks or a helper extension.
A practical extension uses CATransaction to execute completion after animation commits.
This pattern is simple and works well for many UIKit flows.
Transition Coordinator Based Approach
If the current view controller has an active transition coordinator, you can register a completion callback on it. This is often a cleaner way to synchronize with navigation animation state.
This avoids guessing animation durations and ties completion directly to transition completion.
Choosing Between Approaches
Use navigation controller extension when you need a reusable API and consistent call sites. Use transition coordinator callbacks when completion should be tightly coupled to the current view controller transition context.
In many apps, both approaches coexist. A shared extension handles most flows, while coordinator callbacks handle advanced interactive transitions.
For flows with no animation, ensure completion still runs immediately. Both patterns should account for this so business logic stays reliable in unit tests and accessibility settings that reduce motion.
Testing and Reliability
Navigation completion bugs often appear as flaky UI tests. Add tests that assert side effects occur after pop, not before. In integration tests, wait for the expected notification or state change rather than sleeping for a fixed delay.
Also check interactive back gestures. Users can start a swipe and cancel it, which means code that assumes successful pop may produce incorrect updates. Coordinator callbacks help distinguish completion from cancellation paths.
If your app sometimes pops multiple controllers at once, mirror the same completion strategy in helpers for popToViewController and popToRootViewController. Keeping one consistent navigation completion API across these methods reduces duplicated edge case handling and improves maintainability. Centralized helpers also make it easier to instrument navigation timing metrics in one place. Metrics then show transition regressions early during release testing. It also simplifies performance dashboards.
Common Pitfalls
A common mistake is running dependent logic on the line after popViewController. That code executes before animation completion and can race with UI updates.
Another issue is hardcoding animation duration with DispatchQueue.main.asyncAfter. Duration changes across devices and UIKit versions, so fixed delays are brittle.
Developers also forget cancellation paths for interactive transitions. If the pop is canceled, completion logic may need to skip state changes.
Finally, triggering heavy network work on the main thread inside completion can freeze the next screen. Move expensive work to background queues and update UI on main thread when done.
Summary
popViewControllerreturns immediately and has no native completion argument.- Use
CATransactionextension or transition coordinator callbacks for sequencing. - Avoid fixed delay timers for transition completion logic.
- Handle interactive gesture cancellation paths explicitly.
- Keep completion handlers lightweight to maintain smooth navigation.

