Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

viewDidAppear not firing ever again after app enters foreground

I have traced a problem in my iPhone app code to the viewDidAppear method not always firing. When you start the app the event fires as expected. However if I close the app using a phone capable of multitasking and reopen in. My viewDidAppear events no longer fire.

My views are loaded from Nibs and I use viewDidUnload to clean up (release and nil all outlets). My views are nested in side and tab bar then navigation controllers. I looks like the events aren't wired up properly when the nibs reload. Any idea on what I'm doing wrong/missing and how I can fix this?

Thanks in advance.

UPDATE I do not mean the event is not fired when the app first comes into the foreground. I mean the event never fires again. Even when changing between tabs or moving though the navigation views.

Example:

- (void)viewDidAppear:(BOOL)animated {
   [super viewDidAppear:animated];
   NSLog(@"viewDidAppear called");
}

This code is placed in two views, each on different tabs. Each time I swap between tabs "viewDidAppear called" is written to the log. When I close and reopen the app and swap between tabs this no longer happens. Other button events fire normally.

like image 218
Magpie Avatar asked Mar 24 '11 09:03

Magpie


People also ask

Why does viewWillAppear not get called when an app comes back from the background?

The Simple Answer The technical reason for when viewWillAppear gets called is simple. Notifies the view controller that its view is about to be added to a view hierarchy. It can't be any view hierarchy — it has to be the one with a UIWindow at the root (not necessarily the visible window).

What happens between viewWillAppear and viewDidAppear?

There is a noticeable pause after row selection and before the new view is pushed. Some logging indicates that all of my code is reasonably quick, from row selection until the pushed controller's viewWillAppear . But then the time between viewWillAppear and viewDidAppear is logged at around 0.7 seconds.

What is the difference between viewDidLoad and viewDidAppear?

The difference between viewDidAppear and viewDidLoad is that viewDidAppear is called every time you land on the screen while viewDidLoad is only called once which is when the app loads.

What is called after viewDidAppear?

viewDidAppear is called once you see the loaded view on screen. It is called after view appeared. ViewDidAppear is called everytime when you see the view after it is loaded. if you push and then pop any other viewController on that view then again viewDidAppear gets called.


2 Answers

Btw, the viewDidUnload method is really badly named btw -- it's not an 'opposite' to viewDidLoad, it's only called if there was a low memory situation and the view for that controller was unloaded due to not being visible at that time.

(ORIGINAL, NOT SO RELEVANT ANSWER:)

Please see my answer to this similar question:

Why does viewWillAppear not get called when an app comes back from the background?

Basically, viewDidAppear gets called after your UIViewController's view was added to the application's UIWindow heirarchy. Backgrounding then restoring the app doesn't change your view in that respect, so viewDidAppear doesn't get called -- it's correct behaviour, and not a bug. Check out the API docs for UIViewController.

like image 158
occulus Avatar answered Sep 20 '22 18:09

occulus


Found it.

While not new to programming I am new to iPhone development. On researching this problem I found it was not recommended to call the viewWillAppear and viewWillDisappear methods manually.

My viewWillDisappear methods resign any keyboards if shown, when my app enters the background it loads a splash screen ready for when the app re-enters the foreground (there is some logic I need to do to work out what the user is shown on restarting the app and I can do this under the splash screen).

As viewWillDisappear is not called when the app goes into the background to make sure no keyboards appeared over my splash screen I was calling viewWillDisapper in the applicationDidEnterBackground method. I guess this also un-registers my events.

By adding viewWillAppear to my applicationDidEnterForeground method my events started firing again. Lesson learned, I will refactor this so I don't call these events manually.

Thanks for the help.

like image 44
Magpie Avatar answered Sep 19 '22 18:09

Magpie