Presenting Modal Views Bug
While continuing on the retooling of the iPhone book I ran into an irritating bug that has a very simple work around.
When you present a modal view controller via the presentModalViewController:animated: method the viewWillAppear: method gets called on the modal view controller before the view is actually loaded. This is a pain in the neck for me because I set the values for my GUI bits in this method. It was very irritating to see all my outlets being nil when they clearly should have been set to the connections I made in IB.
I found the bug by breaking in a much later method (one of the actions my modal VC implemented) and of course everything was set up as it should be (otherwise the action would not have been invoked). That led me to implement viewDidLoad and that is where I found that viewDidLoad was being called after viewWillAppear:
Fortunately this bug has a really simple work around. Before you present your view controller make it load its view by calling the view method. Here is some sample code.
- (IBAction)modal {
[self.second view];
[self presentModalViewController:self.second animated:YES];
}
Hope this helps someone avoid the hour or so it took me to track this down. I would expect this to be fixed in a upcoming release so this is not a long term need, but for your 2.2 apps it will hopefully help.









Bill--
Isn't that the whole idea, though? That viewWillAppear: is called before your view is loaded, and viewDidLoad is called afterwards? Why is that a bug?
Couldn't you make your view invisible, do your UI setting in viewDidLoad, and then make it visible?
Posted by Chris Ryland on April 25, 2009 at 05:09 PM MDT #
Ouch! That actually seems a little hard to believe...are you sure super's version of -viewWillAppear: doesn't do the loading for you, if necessary?
Of course, this has the same effect, but I'm wondering if they really missed this.
Posted by Jordy/Jediknil on April 25, 2009 at 05:09 PM MDT #
@Chris, nope viewWillAppear: should have all the stuff from IB configured before its called. That is how it works for all other circumstances I've encountered anyway. And the docs lead me to believe that too.
Posted by Bill Dudney on April 25, 2009 at 05:11 PM MDT #
I second Chris' comment - the fact the method has the word "WILL" and not "DID" in it implies that the view hasn't shown yet..
I don't think this is a bug at all - everything is working as expected.
Now I think I WILL go have a beer ;-)
Posted by Dunk on April 25, 2009 at 07:25 PM MDT #
I (by happenstance) haven't hit that one, but I've run across all kinds of other annoying ViewController behaviors that I haven't taken time to deconstruct.
luckily self.view is a fairly easy workaround,
@Chris my expectation is view can be loaded and unloaded as the system desires, but that execution would be outside the appearances:
example:
-view load
--view appears
--view disappears
--view appears
--view disappears
-view unloaded
-view reloaded
--view appears
...
Posted by Bill Shirley on April 26, 2009 at 08:55 AM MDT #
Bill, if I read this right, only when you go through the presentModal code does this order occur? So either this pathway has a bug, or all the other pathways are wrong. It seems silly to me that that by the time you're being notified that a view will appear, that it wouldn't have already been loaded.
I'm trying to find in the docs what the expected order of method calls are, but can't find it yet.
Maybe you should open a ticket with ADC.
Posted by Patrick Burleson on April 26, 2009 at 08:55 AM MDT #
In an earlier release (iPhone 2.1 I think) it worked the way you expected.. Outlets were hooked up at the 'willAppear' -- I was quite suprised to see it change in 2.2 so that they no longer were set on the 'willAppear' methods.
At the time when I (painfully) discovered this I assumed there was some madness to Apple's methods on this one..... (Although I've never understood *why* you wouldn't want the view hooked up on the willAppear method)
Posted by John McLaughlin on April 27, 2009 at 03:54 PM MDT #