Getting the interface orientation in iOS
One feature that annoys me while developing for the iPad is that no matter how much I take care of coding device orientation correctly, I know that eventually the client will use the device faced-up on his desk while in landscape and come back to me: "the orientation is messed up and displays in portrait while in landscape". (NB: this is also true while coding for the iPhone but you do not really focus that much on multiple orientations)
The reason is that while facing-up, UIDevice does not return the interface orientation but the actual device orientation, in this case UIDeviceOrientationFaceUp. So far so good, but problems arise when you need to switch view controller. Not every element in your view are autoresized and you will need to perform some repositioning based on the interface orientation. Since the device has actually not been rotating (you arrived to this view with the device already been rotating to landscape) the following methods will obviously not been called
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)
interfaceOrientation ;
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)
toInterfaceOrientation duration:(NSTimeInterval)duration ;
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)
fromInterfaceOrientation ;
The last option you have is to manually check the device orientation by calling
[[UIDevice currentDevice] orientation]
And here comes the problem, if the user actually holds the device to a valid orientation, you will be able to map the interface orientation to the device orientation given that
typedef enum {
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
} UIInterfaceOrientation;
But in our case where the device is actually facing up on the desk, the device orientation will not map to any interface orientation and the only option we have is to make an arbitrary decision with 50% chance of being wrong. This is obviously unacceptable and there might be an easy solution to this very annoying drawback.
Well, my first thought was to check the application frame by checking
[[UIScreen mainScreen] applicationFrame]
but the frame is orientation independent and simply returns the frame in portrait mode.
The method that seems to actually do the job is to check the status bar orientation. Indeed, if you do not try to manually set its orientation, the status bar gently follows the orientation of the screen and thankfully its orientation is directly available by getting
[[UIApplication sharedApplication] statusBarOrientation]
This way, you can get the interface orientation at any time by simply checking this property. Note that it does not matter whether the status bar is hidden or not, the property will be updated no matter what.
Hope that helps! ;)