Take the 2-minute tour ×

I have seen a couple of articles about ViewWillAppear and ViewDidAppear not firing under certain circumstances but I'm still wondering what the thinking behind the behavior is and how I can work around it in my specific case.

  • window has one view which is handled by a deafult UIVieController and contains a button.
  • Clicking the button presents another view controller modally (VC_MAIN).
  • Depending on settings, the modally shown view controller (VC_MAIN) will either present view A or view B.
  • View A and B are handled by different view controllers (VC_A and VC_B).
  • None of the ViewWill* or ViewDid* methods is called in VC_A or VC_B.
  • I can work around it by calling them manually in VC_MAIN in the corresponding ViewDid* and ViewWill* methods. But if VC_MAIN decides to switch from VC_A to VC_B this does not help. VC_MAIN's View* methods won't be called again and neither will VC_A's or VC_B's.

I could of course dimiss VC_MAIN when switching from A to B, but I don't want to. I want to animate the switching and not just open another modal view.

Why the heck don't those methods get called? It really is beyond me! If you look at UISplitViewController: it houses two sub controllers, which can show other controllers. They basically do the same as I'm trying to do. Has Apple placed kludges all over the code?

share|improve this question
Is the capital V in ViewWillAppear a typo? The method is named viewWillAppear:. As all method names it starts with a lower case letter. –  Matthias Bauch Mar 11 '11 at 14:24
Ah, sorry. I'm using MonoTouch. I added a tag. But the issue is the same in MT and ObjC. –  Krumelur Mar 11 '11 at 14:25
add comment

3 Answers

up vote 1 down vote accepted

My experience with this kind of issue:
If you have a view controller VC managing a main view V and this view has a subview V' managed by another view controller VC', viewWillAppear: and other methods like willRotateToInterfaceOrientation: are not sent to VC'.

What you could to is manually forward these calls from VC:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [mySubViewController viewWillAppear:animated]; // VC'

(Note: I'm not familiar with MonoTouch so I answered with ObjC code)


It reminded me that the View Controller Programming Guide states clearly:

Each custom view controller object you create is responsible for managing all of the views in a single view hierarchy. [...] The one-to-one correspondence between a view controller and the views in its view hierarchy is the key design consideration. You should not use multiple custom view controllers to manage different portions of the same view hierarchy.

share|improve this answer
That I already do. The problem is that if I change the mySubViewController to something else, the VC.viewWillAppear won't get called again (it has already appeared). Therefore mySubViewController's viewWillAppear: won't fire either. And I don't see a way to fix it but changing my design. :-( –  Krumelur Mar 11 '11 at 14:55
@Krumelur Yes, I don't see a valid fix for that, especially if it is a design decision from Apple (yet in some cases I'd like the ability to nest view controllers too). I've included the quote from the docs in my answer... –  Jilouc Mar 11 '11 at 15:06
I guess apple's point of view is that views may or may not have viewcontrollers associated to them. Having to go thru all the subviews every time looking for views would be a waste of time, so its better just to let developers handle it as necessary. –  Eduardo Scoz Mar 11 '11 at 16:44
But how is Apple handling it? Take UINavigationController. You push another controller on it and all view* will fire. But as we see, they don't fire automatically. So what was Apple's decision? DO the fire or NOT? This is what I find so odd. And UINavigationController EXACTLY has several controllers to manage one view hierarchy which is the exact opposite of what the guide states. Same is true for UISplitViewController. Why is Apple making such exceptions to the rule and tells US not to do it? And how did THEY solve it? –  Krumelur Mar 12 '11 at 11:56
add comment

What I would guess as a reason is the step between



If you read the introduction in the view controller programming guide from Apple, they recommend only having one view controller per screen, even if it manages multiple views or a hierarchy of subviews. It would probably be better to manage the views A and B directly in the VC_MAIN, then you would get the notifications you need. If you for any reason preffer the way of having separate view controllers, you might have to notify them by yourself.

share|improve this answer
But that's just not possible. ONE screen might have a UISplitViewController with a UINavigationController left, with a UIViewController on the right, with a UIViewController on TOP presented modally... –  Krumelur Mar 11 '11 at 14:57
add comment

You should really manually call those methods. Its a custom way of managing and showing VC views, so its up to you to determine when each sub-viewcontroller receives the lifecycle calls. In VC_MAIN, create a showVC:newVc method that will call

[newVc viewWillAppear]
[mainView addSubview:newVc.view]
[newVc viewDidAppear]

similarly, create a hideVC: that will call viewWill/DidHide

on your VC_Main viewWillAppear, call the showVC method apropriatelly based on the current config, and everytime you switch your views, the methods will be correctly called.

Its an old question, that was partially handled on iOS5 but still works fine in this fashion, and is fully backwards compatible up to iOS3.

share|improve this answer
add comment

Your Answer


