When I run my app in landscape mode, the second time my view controller’s view is loaded and loadView is called, iOS 5 is not rotating the root view controller’s view away from portrait, nor is it calling the view controller’s willRotate / willAnimateRotation / didRotate methods.
As mentioned, this happens only after the view is unloaded and loadView is called the second time. In my app, I sometimes unload a view controller’s view programmatically before I set it as the root view controller. However, this also happens when the view controller’s view is unloaded automatically due to a low memory warning.
This only happens on iOS 5, not iOS 4.x. It’s easy to reproduce in iOS simulator, and here is a link to a stand-alone test app that reproduces this problem:
http://www.mediafire.com/file/7ob5xw5ym02pasx/ViewControllerTest.zip
To see the issue, just compile the app and start it in landscape mode with iOS 5.0 Simulator, then tap “A” and then “Back”, and you’ll see how the rotation doesn’t occur.
Any ideas? Does this have to do with how I’m setting window.rootViewController?
I debugged through it and there seems to be a change between 4.3 and 5.0. In 4.3 UIKit calls
[UIWindow addRootViewController:], in 5.0 it calls[UIWindow setRootViewController:]. So maybe something changed that we can’t see…I’d suggest working around this, by not using
[newController setupStuff](thus not setting the view to nil), but rather overridingand resetting the (already loaded) view, before it actually appears on screen.
Additional info:
a) you don’t need to set the view to nil. The system does that for you. When you access the view property of that view controller the next time, the system calls
loadViewto recreate the view:b) It all boils down to behavior in iOS 5 regarding the window’s
rootViewControllerproperty. In iOS 5 these two are not equivalent:vs
The former completely ignores orientation, the latter doesn’t.
To make things even more complicated, if one does not override
loadView, but instead lets the system auto-create an empty UIView and only modifies that view inviewDidLoad, a memory warning won’t automatically set the view to nil and release it – docs:Magic. Depending if one overrides the method or not. I can’t really test this in any way.
Case 1 – overridden
loadView:Triggering the memory warning calls both
didReceiveMemoryWarningandviewDidUnloadCase 2 – no
loadView:Triggering the memory warning in simulator only calls
didReceiveMemoryWarning, but notviewDidUnloadI’d say, add the view manually…
cheers.