5

I work on an application, where I have a problem with my view[Will/Did]Disappear methods not being fired when returning to the app.

The case is, I have 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 following (simplified) code is run in my AppDelegate:

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [(UINavigationController *)self.window.rootViewController popToRootViewControllerAnimated:NO];
    [self.window.rootViewController presentModalViewController:loginViewController animated:NO];
}

When I pop off the view controllers on my navigation controller stack, I would expect the view[will|did]disappear methods to be called. However, this is not the case, since they are (apparently) not on the screen anymore when iOS are going to fire these methods. It seems that the modal view controller has taken over.

If I do not present the modal view controller, the view[will|did]disappear methods are called as expected.

My question is: If I want the view[will|did]disappear methods to be called, how can I then structure my code? Is there a better place to present my modal loginViewController?

Edit:

In order to show my problems more clearly, I have created a very simple test project here: https://github.com/JohanVase/ModalViewCauseMissingViewDisappearCalls. Please try a couple of times to follow the instructions in the app, and see that I do not get my "resources" released in my viewWillDisappear method.

JRV
  • 1,702
  • 1
  • 17
  • 27
  • Are those view controllers did appear first? IMHO when app becomes active and you pop to root view controller instantly, those stacked viewControllers didnt have any chance to show up and consecutively disappear – pro_metedor Aug 08 '13 at 14:25
  • Would calling them manually suffice? [someViewController viewDidDisappear]; – carlossless Aug 08 '13 at 14:26
  • 1
    What are you doing in `viewDidDisappear`? – Marcus Adams Aug 08 '13 at 14:28
  • what operations do you perform in viewdidappear viewwilldissapear – Radu Aug 08 '13 at 14:52
  • @Radu and @MarcusAdams: I my `viewDidDisappear`, I do some cleanup (like `NSNotificationCenter removeObserver:`), and I save the data, the user entered (for recovering that information if he returns to the screen). – JRV Aug 08 '13 at 18:17
  • @mindw0rk I have thought about calling them manually, but don't like the idea, if there is any way that I can make use of the automatic calling that the framework will usually take care of :-) – JRV Aug 08 '13 at 18:19
  • is viewWillAppear called or not ? – Vaibhav Gautam Aug 08 '13 at 18:21
  • @pro_metedor: Before I pressed the home button, the views appeared. I have to clean up, as I wrote in a previous comment. Therefore, I need a call that tells my View Controller that it is now no longer shown, and that it can clean up its resources. – JRV Aug 08 '13 at 18:22
  • @VaibhavGautam: `viewWillAppear:` is not called when returning to the app due to the modalViewController being presented just after I call `popToRootViewController:`. But `viewWillAppear:` is called if I comment out the call to `presentModalViewController:` (but this is obviously not what I want :-) ) – JRV Aug 08 '13 at 18:24
  • Brother if viewWillAppear is not being called then viewDidDisappear will never be called too. please see this http://stackoverflow.com/questions/9621346/viewdiddisappear-not-called-when-use-presentviewcontroller?rq=1 – Vaibhav Gautam Aug 08 '13 at 18:30
  • I know - neither of them are being called if I present a modal viewcontroller in applicationDidBecomeActive. So how do I ensure that I release my resources? I do not want a memory leak in my app :-) – JRV Aug 08 '13 at 18:39

1 Answers1

8

I finally asked Apple Technical support the same question. They concluded that this was a bug in iOS, so I have filed a bug report to Apple. The same bug seems to appear in iOS 6 and in the latest iOS 7 (Beta 5).

Apple Technical Support suggested the following:

As a workaround, you can move your cleanup code to a separate method which the AppDelegate would then invoke on the navigation controller's top view controller, before it pops the entire navigation stack.

However, I think this exposes too much of my details in the view controller, so I chose to implement it using willMoveToParentViewController: instead. This method is called when the view controller is removed from its parent, and it is called properly.

JRV
  • 1,702
  • 1
  • 17
  • 27