views:

2292

answers:

5

Hey guys,

I need to know when my view controller is about to get popped from a nav stack so I can perform an action.

I can't use -viewWillDisappear, because that gets called when the view controller is moved off screen for ANY reason (like a new view controller being popped on top).

I specifically need to know when the controller is about to be popped itself.

Any ideas would be awesome, thanks in advance.

+4  A: 

I don't think there is an explicit message for this, but you could subclass the UINavigationController and override - popViewControllerAnimated (although I haven't tried this before myself).

Alternatively, if there are no other references to the view controller, could you add to its - dealloc?

Tom Elliott
The dealloc will only be called *after* the pop, though, not before.
Jesse Rusak
I don't think that's the best solution. I want to use this controller in other places in the app, and the behaviour I want to execute is specific to this controller and has to happen when the controller is popped. I don't want to have to subclass every navController this viewController appears in.
Jasarien
It seems that this is best solution. It seems to work, so thanks!
Jasarien
Try this: subclass UIViewController, override popViewController:animated: and send a custom message to the UIViewController's delegate. Then, the delegate can decide what it needs to do in each case.
Alex
A: 

Maybe you could use UINavigationBarDelegate's navigationBar:shouldPopItem protocol method.

François P.
I tried that first. However, my Navigation Bar is managed by the navigation controller, and manually setting the delegate of the bar to be my view controller results in an exception that explains manually setting the delegate on the nav bar is not allowed if the bar is managed by a nav controller.
Jasarien
+3  A: 

You can catch it here.

  • (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;

    if (viewController == YourAboutToAppearController) { [do something] }

This will fire just before the display of the new View. Nobody's moved yet. I use all the time to do magic in front of the asinine NavigationController. You can set titles and button titles and do whatever there.

dieselmcfadden
A: 

This is working for me. - (void)viewDidDisappear:(BOOL)animated { if (self.parentViewController == nil) { NSLog(@"viewDidDisappear doesn't have parent so it's been popped"); //release stuff here } else { NSLog(@"PersonViewController view just hidden"); } }

Ronald Nepsund
This is exactly what I needed. Thanks.
grahamparks
This doesn't work with 4.1.
chrish
A: 

I have the same problem. I tried with viewDisDisappear, but I don't have the function get called :( (don't know why, maybe because all my VC is UITableViewController). The suggestion of Alex works fine but it fails if your Navigation controller is displayed under the More tab. In this case, all VCs of your nav controllers have the navigationController as UIMoreNavigationController, not the navigation controller you have subclassed, so you will not be notified by the nav when a VC is about to popped.
Finaly, I solved the problem with a category of UINavigationController, just rewrite - (UIViewController *)popViewControllerAnimated:(BOOL)animated

- (UIViewController *)popViewControllerAnimated:(BOOL)animated{
   NSLog(@"UINavigationController(Magic)");
   UIViewController *vc = self.topViewController;
   if ([vc respondsToSelector:@selector(viewControllerWillBePoped)]) {
      [vc performSelector:@selector(viewControllerWillBePoped)];
   }
   NSArray *vcs = self.viewControllers;
   UIViewController *vcc = [vcs objectAtIndex:[vcs count] - 2];
   [self popToViewController:vcc animated:YES];
   return vcc;}

It works well for me :D

hiepnd