I have the following environment:
- root view controller is UINavigationController
- a number of custom UIViewControllers may be pushed on the navigation stack
- each of custom controllers may or may not present a modal view controller
- I need to be able to programmatically manage the navigation stack (for example – drop all controllers from the navigation stack except the root controller as response to some external event like push notification delivery)
Naive implementation with [navigationController setViewControllers:newControllers animated:animated]; obviously fails if there was a modal view controller presented by any of old controllers ind the stack:
- This modal controller stays visible
- If a delegation pattern is used for parent<->modal controllers communication (parent is delegate of presented modal view controller) any action in modal view controller results in crash since delegate was already released
So the general problem is that modal controler lifcycle is not bound to the parent controller. My questions are:
- Is there a stadard approach for managing this kind of hierarchy and safe navigation stack changes?
- If NO than what would be a best custom implementation? I’m seeing two general approaches – one is to explicitly dismiss/unlink all modal contrellers in the code changing the navigation stack, the other is to add logic to parent view contollers to manage modal controllers lifecycle directly.
There is no standard approach because this behaviour is discouraged by the HIG. Even in the event of push notifications, you’re not supposed to modify the existing stack except through pushes, pops, and pop-to-root. However, what you’re asking is completely possible.
You have several options, but the best is probably notifications. Use
NSNotificationCenterin your app delegate to let any interested view controller’s know that you’re about to pop to your root view controller. In each of your modal view controllers, register for this notification name and dismiss yourself when notified. After dismissing your modals, you can just usepopToRootViewControllerand avoid messiness with modifying the stack.Take a look at TweetBot and see how they handle push notifications. They do a pretty good job, I believe, and they just present a new modal view controller. You can do this (nested modal presentations), so experiment around and see what you can do without jarring the user.