Device orientation is of course the orientation that the device is currently being held in, while interface orientation is the orientation of the running app’s user interface.
What I was trying to do was to hide the status bar while in landscape mode and show it in portrait mode for an iPhone app that operates in the 3 principal orientations: portrait, landscape left, and landscape right.
To achieve that I was using code like this:
#pragma mark - Status Bar
- (BOOL)prefersStatusBarHidden
{
return (UIDeviceOrientationIsLandscape([[UIDevice currentDevice] orientation]));
}
#pragma mark - Orientation
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
[self setNeedsStatusBarAppearanceUpdate];
}
This works fine at first blush, especially in the simulator, but not so well in practice. First off, the app doesn’t even support all 4 possible interface orientations (the fourth being upside down portrait), so what happens when the phone is held upside down? Well the interface orientation doesn’t change from its previous orientation (most likely landscape) but the device orientation is not landscape and so the status bar appears. Bug.
But even worse, there are additional device orientations (namely face up and face down) that are neither portrait nor landscape and have no matching interface orientation. If the phone was last in landscape interface orientation and then gets laid flat on the desktop, the device orientation is no longer landscape (it is flat), and so the status bar appears. Bug again.
Just for the record, here’s the definition of UIDeviceOrientation:
typedef NS_ENUM(NSInteger, UIDeviceOrientation) {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait, // Device oriented vertically, home button on the bottom
UIDeviceOrientationPortraitUpsideDown, // Device oriented vertically, home button on the top
UIDeviceOrientationLandscapeLeft, // Device oriented horizontally, home button on the right
UIDeviceOrientationLandscapeRight, // Device oriented horizontally, home button on the left
UIDeviceOrientationFaceUp, // Device oriented flat, face up
UIDeviceOrientationFaceDown // Device oriented flat, face down
};
And here’s the definition for UIInterfaceOrientation:
typedef NS_ENUM(NSInteger, UIInterfaceOrientation) {
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
};
It’s interesting that UIInterfaceOrientation is defined in terms of UIDeviceOrientation.
TL;DR;
So what I should have been doing was this:
#pragma mark - Status Bar
- (BOOL)prefersStatusBarHidden
{
return (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]));
}
This works as expected when the device is upside down or flat.

本文探讨了iOS应用中状态栏在不同设备和界面方向下的隐藏与显示问题,介绍了如何根据不同设备方向正确地调整状态栏的可见性,避免了常见的Bug。
3581

被折叠的 条评论
为什么被折叠?



