- (void)viewWillDisappear:(BOOL)animated
- (void)viewDidDisappear:(BOOL)animated
- (void)viewWillAppear:(BOOL)animated
- (void)viewDidAppear:(BOOL)animated
These are called for the event described in the method name. For example, the viewWillDisappear is called just before the view disappears.
Now for my situation, I needed to trap the event of my controller being popped off. The problem with using viewWillDisappear (or viewDidDisappear) is that it is called in different scenarios. When a controller is pushed on top of yours, the viewWillDisappear method is called. And when your controller is popped off, the method is called again.
The problem for me is the event is too general. Your view is disappearing, but the reason why it's disappearing is not provided. In my situation, my controller can push other controllers, but I only wanted to know when I was popped off, not pushed on top of. In order to differentiate between the two scenarios, I need additional intelligence in my code to determine which situation I am in. Basically, whenever I am about to push on a new controller, I have to set a flag to ignore the next viewWillDisappear message. Then I need to handle the viewWillAppear message to clear this flag. Not a big deal, but seems like a hassle to handle something fairly basic. Here is the framework needed to support this:
But that was my situation. If your controller is at the end of the UINavigationBar hiearchy, meaning you cannot have another controller pushed onto yours, then you are safe assuming that the viewWillDisappear is being called for the scenario where your controller is being popped off. Take caution, though. Should you later change the behavior of your code to allow additional controllers to be pushed, your viewWillDisappear will get invoked in what may be an inappropriate time. One other thing I should mention. There is this warning in the Apple reference in each of the four methods listed above:// --------------------------------------------------------- //
// YourController.h @interface YourController : UIViewController { BOOL ignoreDisappear; } @end // --------------------------------------------------------- // // YourController.m // this helper method will push a new controller onto the navigation stack - (void) myPushController:(UIViewController*) newController { // first, set our flag to ignore the next viewWillDisappear message ignoreDisappear = YES; // now do the push [self.navigationController pushViewController:newController animate:YES]; [newController release]; } - (void) viewWillDisappear:(BOOL) animate { // do we care about this event? if(ignoreDisappear == NO) { // this is your back button handle logic //... } [super viewWillDisappear:animate]; } - (void) viewWillAppear:(BOOL) animate { // clear the flag ignoreDisappear = NO; [super viewWillAppear:animate]; }
Warning: If the view belonging to a view controller is added to a view hierarchy directly, the view controller will not receive this message. If you insert or add a view to the view hierarchy, and it has a view controller, you should send the associated view controller this message directly. Failing to send the view controller this message will prevent any associated animation from being displayed.I'm not real clear on what the phrase "added to a view hierarchy directly" means, but there are numerous reported problems related to this. I don't have these problems myself, but they are reported here and here.
thanks!
ReplyDeleteThe following looks at the navigation stack to determine if the view was pushed or popped:
ReplyDelete- (void) viewDidDisappear:(BOOL)animated
{
NSLog(@"just pushed = %d", [self.navigationController.viewControllers containsObject:self]);
}