Today, a quick note on an iPhone gotcha that recently bit me. The short version is that a UIViewControler's
navigationController
property is cleared when that view controller is removed from its nav. controller, which can trip you up if you’re manipulating that nav. controller in complex ways.
Motivation
I encountered this problem because I was reshuffling a navigation controller stack behind a modal view – i.e. the modal view was to scroll up over one screen, and then scroll down to reveal a different screen, depending upon what the user did in the modal view. The meat of the code looked something like this:
- (void)stageManage
{
// Advance model to the next step, if any
if ([self nextStep])
{
// Update this view
[self.tableView reloadData];
}
else
{
// Dismiss this view, revealing it's parent
[self.navigationController popViewControllerAnimated:NO];
}
// Dismiss modal view(s)
[self.navigationController dismissModalViewControllerAnimated:YES];
}
(stageManage
is a method of the view controller that’s atop the stack before the modal view is displayed, and it is called by the modal view controller via the target-action pattern.)
Difficulties
The preceeding code did not work. The use case in which popViewControllerAnimated:
was called did not behave properly; the modal view was not dismissed.
It turned out that this was happening because the popViewControllerAnimated:
call removed the self
object from its navigation controller, clearing its navigationController
property, and causing the dismissModalViewControllerAnimated:
message to be sent to a nil
object.
Fix
Caching the nav. controller fixed matters right up:
- (void)stageManage
{
UINavigationController* nc = self.navigationController;
// Advance model to the next step, if any
if ([self nextStep])
{
// Update this view
[self.tableView reloadData];
}
else
{
// Dismiss this view, revealing it's parent
[nc popViewControllerAnimated:NO];
}
// Dismiss modal view(s)
[nc dismissModalViewControllerAnimated:YES];
}
Nothing too complex, but puzzling if you’re not looking for it.