17

I work on a legacy application, and have found out, that my view[Will/Did]Disappear methods are not always fired properly.

The case is, I have a (custom) UIViewController set as rootViewController in AppDelegate. This rootViewController has a UINavigationController, which has two view controllers pushed on it. When the user presses the home button, the user is logged out. When he later returns to the app, the application calls [UINavigationController popToRootViewControllerAnimated:YES] and then displays a modal UIViewController for logging in.

The problem is: When I push/pop on the UINavigationController normally, my viewWillDisappear method is called properly. But when I use the popToRootViewControllerAnimated: method, viewWillDisappear is not called on any of the viewControllers that are popped off.

Searching on the internet has only given two possible reasons:

None of these suggestions are the case in my app. And I have no idea where to look. Anybody has a suggestion to what has been done wrong in the app?

Community
  • 1
  • 1
JRV
  • 1,702
  • 1
  • 17
  • 27

2 Answers2

24

The view probably wasn't onscreen. It has to be onscreen (visible) for the viewWillDisappear: method to be called. If it's coming back from the background, it wasn't visible.

You could try using willMoveToParentViewController: which is called when the view controller is removed from its parent.

nevan king
  • 112,709
  • 45
  • 203
  • 241
  • That is a very interesting suggestion! I have now tried using popToRootViewController on another place in the app, and then my viewWillDisappear are called as expected, so you are right so far. However, I also tried making a test app, with exactly my setup, where `popToRootViewControllerAnimated:` is called from AppDelegate's `applicationDidBecomeActive:`. Here, the `viewWillDisappear:` method is also called. This still suggests, that it ought to be called, but something is wrong in my app. – JRV Jul 31 '13 at 05:15
  • 1
    The reason for this to happen turned out to be, that I was presenting a modal view controller when the `applicationDidBecomeActive:` method was called (just after calling `popToRootViewControllerAnimated:`). So your answer was correct - the view apparently was off the screen when the app launched. – JRV Aug 08 '13 at 13:59
  • 1
    After bringing this issue up with Apple' technical support, it turned out to be a bug in iOS (and it appears in both 6 and 7 Beta 5). I have filed a bug report to Apple. I give you +1 for the good suggestion using `willMoveToParentViewController` as a workaround :-) – JRV Aug 15 '13 at 07:36
  • @JRV Good to know, thanks for going to the trouble. You might want to post it on Open Radar (http://openradar.appspot.com/) too so people know about it. – nevan king Aug 15 '13 at 10:43
  • 1
    Interesting page - thanks for pointing it out. I have now posted the bug: http://openradar.appspot.com/14744330 – JRV Aug 16 '13 at 12:42
  • :) Thanks for posting this workaround. I was facing the same problem. – GoGreen Mar 04 '15 at 12:48
0

such useful to me

[nav performSelector:@selector(popToRootViewControllerAnimated:) withObject:nil afterDelay:0.0];

I rewrote UITabBarController

- (void)setSelectedIndex:(NSUInteger)selectedIndex {

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        UINavigationController *navigationController = [originalViewController as:[UINavigationController class]];
        if (navigationController.presentedViewController) {
            [navigationController dismissViewControllerAnimated:NO completion:^{
                [navigationController popToRootViewControllerAnimated:NO];
            }];
        }else if (navigationController.topViewController){
            [navigationController popToRootViewControllerAnimated:NO];
        }
    });

}