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.
viewWillAppear(_:)Always called after viewDidLoad (for obvious reasons, if you think about it), and just before the view appears on the screen to the user, viewWillAppear is called.
In other words, if someone looks at another application or takes a phone call, then switches back to your app which was earlier on backgrounded, your UIViewController which was already visible when you left your app 'doesn't care' so to speak -- as far as it is concerned, it's never disappeared and it's still visible ...
The LifecycleThe view controller lifecycle can be divided into two big phases: the view loading and the view lifecycle. The view controller creates its view the first time the view is accessed, loading it with all the data it requires. This process is the view loading.
viewDidLoad is things you have to do once, you should do things that you only have to do once in viewDidLoad – like setting your UILabel texts. viewWillAppear is called just before the view is displayed. This happens always after viewDidLoad and is called every time the view is displayed.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With