viewWillAppear: not being called inside a UINavigationController
I just stumbled on a small problem that gave me a great headache. I changed the view hierarchy to implement flipping preferences on the back of my App’s main view. Accordingly, I had to move some stuff out of the nibs and into the code. Iin other words, some heavy refactoring, and without testing (I know, bad bad me).
So basically I now have a root UIViewController which has a UINavigationController as a subview; this, in turn, loads a number of UIViewControllers to navigate my items hierarchy.
Today, while working on cosmestic/usability improvements, I realised that something was definitely not working. When moving back and forth in my items, data were not refreshed. This pointed to one culprit, viewWillAppear not being called in the UIViewControllers.
After some googling I found out that if you add a UINavigationController as a subview of a UIViewController subclass, you must explicitly call its viewWillAppear method from its container; otherwise, they won’t be called, and when moving back and forth in the navigation tree, your UIViewControllers’ viewWillAppear: methods won’t be called.
It’s quite simple; assuming that projectNavigationController is a navigation controller added as a a subview of this UIViewController subclass, just make sure you add this simple call:
-(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [projectNavigationController viewWillAppear:animated]; }
Of course the same applies to your other viewWill/Did methods
-(void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [projectNavigationController viewWillDisappear:animated]; } -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [projectNavigationController viewDidAppear:animated]; } -(void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [projectNavigationController viewDidDisappear:animated]; }
It’s quite simple, but wasn’t obvious for me at first.







2009-01-04 at 2.13 am
I have the exact same problem. Mine is a little more insidious.
UIViewController <- top level, its view is the only window subview
UITabBarController <- its view is the only subview of the top level UIViewController view
UINavigationController <- inside one of the tabs
No matter what I’ve tried, I cannot get the UINavigationController to send its messages. Most likely because the UITabBarController doesn’t send its messages either. Evil evil evil.
…any chance you found a way around that one?
2009-01-04 at 11.47 am
Lovedeity, I didn’t have the chance to try something like your hierarchy, but Iwould say that you need to have the root controller forward the calls to the tab bar controller, and the tab controller forward the call to the navigation controller.
So you should include the code I’ve shown both in the root controller and in the tab bar controller. Have you tried something like this? Davide
2009-01-04 at 8.45 pm
I’m pretty sure I tried that, yeah.
My alternative solution is to just start out with the UITabBarController as the subview of the main window. Then whenever I need to show the flipside, I remove that view from the window, add that view as the subview of my flipper controller, add the flipper view to the window, then perform the flip. Not as elegant as I’d like, though.
2009-01-04 at 9.05 pm
Well, if it does the job
Very strange though, just the fact of having to pass these will/did appear calls exlicitly seems weird to me, but I am not a seasoned enough cocoa programmer, I can’t give an informed judgement. If anyone has a comment on my or lovedeity’s issue, please leave a comment .
2009-04-12 at 10.53 pm
Hi,
I had exactly the same problem. UITabBarController does not dispatch the calls to the view controllers it contains. I am testing this on iPhone OS 3 beta 2.
I fixed it by creating a private category of UITabBarController. Create a new category of UITabBarController and implement the viewWillAppear, viewWillDisappear, etc:
@implementation UITabBarController (Private)
@end
2009-06-10 at 8.17 am
[...] here [...]
2009-06-19 at 5.56 pm
Many thanks! I surfed through many forum and blog posts befor i found your solution. Sometimes such basic things are hard to find…
2009-07-23 at 9.42 pm
Thanks! This was driving me nuts but it fixed the issue!!!
2009-08-20 at 10.12 pm
You can also set your root UIViewController as the UINavigationController’s delegate and implement UINavigationController’s delegate method -navigationController:willShowViewController:animated: in your UIViewController. e.g.
2009-10-04 at 12.10 am
I’ve had a similar problem but it’s kind of the inverse.
I have a Navigation-based application setup with the AppDelegate pushing a Navigation Controller that has a UITableView as a sub-view of that. This then pushes more views to the nav controller. Now my problem is that the SUB views are getting the orientation change events no problem, but the root Table View controller NEVER gets them.
Your advice probably translates to my set up, but I can’t figure out how. What am I not getting?
2009-10-20 at 6.40 am
Word to the wise…do not use a root view controller and add views to it like so:
[rootViewController.view addSubview:secondViewController.view];
Where second view controller is a view controller, navigation controller, or a tab bar controller. Bottom line, the only place you should use addSubview on on a view controllers view should be [window addSubview:viewController.view]; You’ll be writing hacks and workarounds throughout your app to keep it working…and those aren’t guaranteed to work in the next OS release…
If you must use a root view controller because you dynamically determine your main application view controller (like I do), use [rootViewController presentModalViewController:secondViewController animated:NO]; Since you’re not animating it, it will appear when the app loads and you’ll never see the root view controller’s view. If you want to flip the second view controller in (like the original post), just present another modal on top with the desired animation….or, wrap presentModal..animated:NO with UIView animations.
2009-12-13 at 4.53 am
This one was really tricky, thanks for the heads up. This seems like a big bug from apple… but oh well that’s what this trials and errors are for.
thanks!
2009-12-29 at 7.46 am
If you set the UINavigationControllerDelegate to some random object (like the navigation view controller) and then add this method:
It will do what you expect.
2010-02-24 at 2.55 am
Thanks, this saved me a load of headaches.
Anyway, your comments template has a formatting error while appending nofollow rel tag to urls in comments.
2010-04-08 at 8.30 am
Thanks a lot. it did work well. you rescue me
2010-04-13 at 7.39 am
I stumbled upon this today and was grateful for your post outlining the fix. It’s a bit naff that it doesn’t just work – the framework shouldn’t need plumbing like this.
2010-05-04 at 8.23 am
Thank you for the clear and succinct explanation. Wish I’d found this post earlier!
2010-06-05 at 5.29 am
You rock! You saved me days of fighting with this issue. Thanks so much for the information. Fixed my problem immediately!
2010-10-14 at 9.50 pm
Thank you! I agree with everyone else, this would have taken me much longer than 30 minutes to figure out. I just implemented the delegate method and it works like a charm.
2010-10-14 at 9.52 pm
Corprew Reed had a good point that I missed. You should do a respondsToSelector: test first.
2010-10-15 at 11.25 am
Thanks to all the folks for your feedback. I am happy this short post saved ye some time. BTW this post is quite old, I can’t be sure it applies also to the lastest SDKs…
2010-10-18 at 11.03 pm
Hey all
Developing on iOS 4.1 and can confirm all these issues still present if you don’t wire up your view hierarchy right.
For me, Dustin Clark’s comment (#11) was the best advice and saved me hours – THANK YOU!
2010-10-20 at 5.46 am
Folks, this is not a bug!
Apple explicitly says that the concept of having couple of subclasses of UIViewControllers encapsulated is not suggested. Just check the documentation (View Controller Programming guide):
“Each custom view controller object you create is responsible for managing exactly one screen’s worth of content. The one-to-one correspondence between a view controller and a screen is a very important consideration in the design of your application. You should not use multiple custom view controllers to manage different portions of the same screen. Similarly, you should not use a single custom view controller object to manage multiple screens worth of content.
Note: If you want to divide a single screen into multiple areas and manage each one separately, use generic controller objects (custom objects descending from NSObject) instead of view controller objects to manage each subsection of the screen. Then use a single view controller object to manage the generic controller objects. The view controller coordinates the overall screen interactions but forwards messages as needed to the generic controller objects it manages.”
So the “official” solution would be if you used a singel UIViewController subclass as the root controller and subclass all your “inner” view controllers from NSObject.
Actually this problem (subclassing from UIViewController vs. NSObject) keeps me suffering for weeks and can’t find the right answer. Almost everyone subclasses the inner controllers from UIViewController however Apple states not to do so…
2010-10-20 at 2.57 pm
Peter, thanks for the info ,I guess I will go back to the docs and read more carefully. I seem to remember that my approach wasn’t that far fetched, but you probably ahve a point. At point (after 18 months) I hardly remember where in my app this caused a problem
2010-11-21 at 11.33 pm
Has anyone got a working solution for the setup that Lovedeity highlighted…
UIViewController > UITabBarController > UINavigationController > UIViewController
?
2010-11-21 at 11.36 pm
to add to the confusion, the above is at the back of a Utility-style flip view.
2010-12-17 at 8.30 am
Your headache saved me a lot of mine!
Thanks a lot! you rock!
2011-01-03 at 5.11 pm
I already had read something like that but totally forgot it ! So thank you very much, helps a lot !
2011-02-09 at 2.08 am
[...] — it turns out that it wasn’t being called at all. A quick net search turned this up — basically viewWillAppear: doesn’t get automatically called (likewise for the over [...]
2011-03-20 at 6.14 am
We are a group of volunteers and starting a new scheme in our community. Your site offered us with valuable info to work on. You have done a formidable job and our whole community will be grateful to you.
2011-03-30 at 9.10 pm
After trying all the various solutions described here, with various degree of success, I found a 1-LINE-SOLUTION in another thread online:
[parentViewController.view addSubview:[subViewController view]]; [subViewController viewWillAppear:NO]; // <– ONE LINE fix
That’s it. After I added that line, all the viewWillAppear, viewWillDisappear, viewDidAppear and viewDidDisappear get propagated through navigation, tabBar and children views.
2011-04-26 at 5.14 am
hi All! You can trie that
-(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; UINavigationController *navController =[self.tabBarController.viewControllers objectAtIndex:appDelegate.indexOfTab]; [navController viewDidAppear:animated]; //[self.navigationController viewDidAppear:animated]; NSLog(@”viewDidAppear:(BOOL)animated”); } -(void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [self.navigationController viewDidDisappear:animated]; NSLog(@”viewDidDisappear:(BOOL)animated”); }
2011-07-14 at 6.37 pm
Quick news on News is just here.
2012-01-05 at 1.37 pm
เพาะกาย
2012-03-04 at 3.01 pm
Great – I should certainly pronounce, impressed with your website. I had no trouble navigating through all tabs as well as related info ended up being truly simple to do to access. I recently found what I hoped for before you know it in the least. Reasonably unusual. Is likely to appreciate it for those who add forums or something, web site theme . a tones way for your customer to communicate. Nice task.
2012-04-08 at 9.16 pm
Incredible quest there. What happened after? Thanks!
2012-05-25 at 4.59 am
We would also like to say that most individuals that find themselves without having health insurance are normally students, self-employed and people who are without a job. More than half on the uninsured are really under the age of Thirty five. They do not sense they are looking for health insurance because they’re young plus healthy. Their particular income is usually spent on homes, food, plus entertainment. Most people that do go to work either full or part time are not presented insurance through their jobs so they get along without as a result of rising tariff of health insurance in america. Thanks for the tips you reveal through your blog.
2012-06-01 at 1.02 pm
forty individuals that function with all of the services Oasis provides, and he is really a really busy man, he
2012-10-20 at 12.44 pm
Thanks for one’s marvelous posting! I really enjoyed reading it, you happen to be a great author. I will make sure to bookmark your blog and definitely will come back in the foreseeable future. I want to encourage yourself to continue your great work, have a nice day!
2012-10-25 at 11.31 am
I am not sure where you are getting your info, but great topic.
I needs to spend some time learning much more or understanding more. Thanks for wonderful info I was looking for this info for my mission.
2013-04-09 at 9.51 pm
Well If you live in the Dayton Area Check https://daytondonations.com
2013-04-10 at 4.40 am
The Zune concentrates on being a Portable Media Player. Not a web browser. Not a game machine. Maybe in the future it’ll do even better in those areas, but for now it’s a fantastic way to organize and listen to your music and videos, and is without peer in that regard. The iPod’s strengths are its web browsing and apps. If those sound more compelling, perhaps it is your best choice.
2013-05-26 at 1.01 pm
There is a Cherry-Almond Smoothie in the book will be Gaga s dangerous dieting tips to lose weight habits. Lastly, when trying to conceive and throughout the pregnancy dieting tips to lose weight is a good starting point. For the proper absorption of zinc, you must be on the diet. Invariably though, the diets fail people and they are not all the same.