iPhone rotation woes and a workaround
My story's often told: app meets UITabBarController
, UITabBarController
starts an affair with multiple UINavigationController
s, the UINavigationController
s end up with a host of child UIViewControllers
, some of which need to rotate to landscape mode and some that don't.
So far, so good.
Then, the plot thickens! In comes an MFMailComposeViewComposer
that you want to display via presentModalViewController
. Your view's in landscape, you tap the button that brings up the modal mail compose screen and – oh, the injustice, the tragedy – it flips your view to portrait mode before displaying itself.
Bummer!
Of course, there's more to the story. You had started rotating your views yourself using CGAffineTransform
s when you saw that getting autorotation to work via shouldRotateToInterfaceOrientation
for complicated view hierarchies required a four year degree in Voodoo. Now, you feel you may be paying for your insolence for deviating from the One True Path of the Church of the Holy Apple DDFS. (I don't know what DDFS stands for but it makes names cooler when they have random letters after them.)
So you dig deeper. It appears that your view controllers all return UIInterfaceOrientationPortrait
when queried for their interfaceOrientation
properties, even when the device is in one of the landscape modes. (Note the subtle impedance mismatch between "interface" and "device" in the previous sentence, it's a clue!) Aha, and it appears that either presentModalViewController
or MFMailComposeViewController
is looking for that value and, being the control freak that it is, actually forcing the layout to that orientation before displaying itself.
Well, there's another control freak in town, buddy, and there ain't room enough for the both of us!
So what's a control freak with a scripting background to do but monkey patch this baby… categories to the rescue! If I can get the interfaceOrientation
method to return the actual orientation of the device, instead of the interfaces's orientation, it should work!
@interface UIViewController(OrientationPatch)
-(UIDeviceOrientation)interfaceOrientation;
@end
@implementation UIViewController(OrientationPatch)
-(UIDeviceOrientation)interfaceOrientation
{
return [[UIDevice currentDevice] orientation];
}
And it does… somewhat. Now the MFMailComposeViewController
is displaying properly but reverts the app to portrait when it is dismissed! Doh!
More investigating and it appears that shouldRotateToInterfaceOrientation
is now being called on my UITabBarController
and, since it wasn't implemented, is now returning NO
to everything.
I know how to fix that: subclass UITabBarController
and implement shouldRotateToInterfaceOrientation
:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
Et, voilà, the MFMailComposeViewController
now displays perfectly in landscape mode and excuses itself gracefully without blowing down the whole house.
None of this should be considered great advice to follow. Having found shouldRotateToInterfaceOrientation
too painful to work with in my view hierarchy, I resorted to rotating my views myself (since I support rotation in just one, clearly defined section of my application, this has so far proven much easier to implement). If you can get things working with shouldRotateToInterfaceOrientation
, you should stick to that. If you, however, find yourself in rotation hell like I did, maybe some of the above will make sense to you and lead you to diagnose or even fix the issues you may be encountering.
Regardless, it definitely feels like autorotation support, especially selective autorotation support for complex view hierarchies, is something that the iPhone SDK team could concentrate a bit on for future releases.
Comments
by Aral on 2009-08-19 12:10:20
by Aral on 2009-08-18 15:48:34
by Keith Peters on 2009-08-18 16:58:30
by JohnB on 2009-08-31 02:26:16
by Aral on 2009-08-29 18:22:19
by Alin on 2009-10-28 14:14:41
by Steve Denenberg on 2009-08-29 17:49:02
by Kenneth on 2009-08-18 15:45:20
by smallduck on 2009-10-28 19:07:18
by Steve Denenberg on 2009-09-02 14:41:38
by Steve Denenberg on 2009-08-29 18:35:29
by nicolás on 2010-01-13 10:39:49
by Shawn Arney on 2010-02-03 02:04:21
by Erik on 2010-05-05 17:35:30
by Rohit on 2010-05-14 20:02:01
by Marc on 2010-07-15 00:26:12
by Neil on 2010-09-11 16:14:09
by Yash on 2010-10-24 17:38:49
by Ariel on 2011-03-10 22:27:46
by Ilias on 2011-05-25 06:06:42
by YUVARAJ.M on 2011-06-23 10:27:54
by Andrius Bolsaitis on 2011-09-17 13:50:51
by Sajeeb Saha on 2011-10-02 08:22:32
by Rad on 2012-04-10 14:17:15
by Edgar Arroyo on 2012-05-12 18:37:49