views:

2228

answers:

3

I'm struggling to find a good solution to this problem. In a view controller's -viewWillDisappear: method, I need to find a way to determine whether it is because a view controller is being pushed onto the navigation controller's stack, or whether it is because the view controller is disappearing because it has been popped.

At the moment I'm setting flags such as isShowingChildViewController but it's getting fairly complicated. The only way I think I can detect it is in the -dealloc method.

A: 

I assume you mean that your view is being moved down the navigation controller's stack by the pushing a new view when you say pushed onto the stack. I would suggest using the viewDidUnload method to add a NSLog statement to write something to the console so you can see what is going on, you may want to add a NSLog to viewWillDissappeer.

Aaron
+5  A: 

You can use the following.

- (void)viewWillDisappear:(BOOL)animated {
  NSArray *viewControllers = self.navigationController.viewControllers;
  if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
    // View is disappearing because a new view controller was pushed onto the stack
    NSLog(@"New view controller was pushed");
  } else if ([viewControllers indexOfObject:self] == NSNotFound) {
    // View is disappearing because it was popped from the stack
    NSLog(@"View controller was popped");
  }
}

This is, of course, possible because the UINavigationController's view controller stack (exposed through the viewControllers property) has been updated by the time that viewWillDisappear is called.

Sbrocket
Perfect! I don't know why I didn't think of that! I guess I didn't think the stack would be altered until the disappear methods had been called! Thanks :-)
Michael Waterfall
I've just been trying to perform the same thing but in `viewWillAppear` and it would seem that whether the view controller is being revealed by it being pushed or something above it being popped, The viewControllers array is the same both ways! Any ideas?
Michael Waterfall
I should also note that the view controller is persistent through the app's lifetime so I can't perform my actions on `viewDidLoad` as it's only called once! Hmm, tricky one!
Michael Waterfall
A: 

If you just want to know whether your view is getting popped, I just discovered that self.navigationController is nil in viewDidDisappear, when it is removed from the stack of controllers. So that's a simple alternative test.

(This I discover after trying all sorts of other contortions. I'm surprised there's no navigation controller protocol to register a view controller to be notified on pops. You can't use UINavigationControllerDelegate because that actually does real display work.)

dk