Search code examples
iosuiviewcontrolleruiinterfaceorientation

Root UIViewController responds to orientation changes, but second UIViewController does not


I'm posting this because, after battling with this problem for the better part of a day (and many, many Google and StackOverflow searches), I've finally found the problem, but I haven't seen this solution anywhere.

I have an app with a UINavigationController as root controller and two UIViewControllers that are owned by the root controller. All are created programatically, I'm not using Interface Builder at all. Both UIViewControllers are set up to handle rotation in all orientations (allegedly), but only the root UIViewController rotates correctly. For the second UIViewController, shouldAutoRotateToInterfaceOrientation fires once, but never fires again, and willRotateToInterfaceOrientation never fires at all.

The problematic view controller has only standard controls for subviews: a UILabel, a UITextView and a UISwitch. It doesn't include a tabBar or any other view controller as a subView. The View and VC are both in scope and seem otherwise healthy. All interaction with the view works correctly except for the rotation.

I'm specifically calling:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications

and implementing:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:@"UIDeviceOrientationDidChangeNotification" object:nil];

along with the didRotate method did not make a difference.


Solution

  • The issue that I found was a stupid one on my part: I was calling alloc on the view controller instance without an init (got lost in an edit, in my defense). The thing that made it so surprising was that the view functioned correctly in all other respects. I had read this Apple Technical Q&A: http://developer.apple.com/library/ios/#qa/qa1688/_index.html , but hadn't connected it with the problem I was seeing. The key line is the last sentence: For the object to be initialized properly, you must call super on any init or initWithNibName method you are overriding for your view controllers. Since init never got called at all, of course [super init] never happened either.