UIDeviceOrientationFaceUp - how to distinguish between portrait and landscape?
I make this code skeleton for dealing with wanted & unwanted devices orientations, in my case i want to ignore the UIDeviceOrientationUnknown, UIDeviceOrientationFaceUp and UIDeviceOrientationFaceDown, caching the last allowed orientation. This code deals with iPhone and iPad devices and can be useful for you.
- (void)modXibFromRotation {
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
NSString *device = [[UIDevice currentDevice]localizedModel];
UIInterfaceOrientation cachedOrientation = [self interfaceOrientation];
if ([device isEqualToString:@"iPad"]) {
if (orientation == UIDeviceOrientationUnknown ||
orientation == UIDeviceOrientationFaceUp ||
orientation == UIDeviceOrientationFaceDown) {
orientation = (UIDeviceOrientation)cachedOrientation;
}
if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) {
/* Your code */
}
if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {
/* Your code */
}
}
if ([device isEqualToString:@"iPhone"] || [device isEqualToString:@"iPod"]) {
if (orientation == UIDeviceOrientationUnknown ||
orientation == UIDeviceOrientationFaceUp ||
orientation == UIDeviceOrientationFaceDown) {
orientation = (UIDeviceOrientation)cachedOrientation;
}
if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) {
/* Your code */
}
if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {
/* Your code */
}
}
}
As of iOS13 use
UIInterfaceOrientation orientation;
if (@available(iOS 13.0, *)) {
orientation = self.window.windowScene.interfaceOrientation;
} else {
orientation = [[UIApplication sharedApplication] statusBarOrientation];
}
You should not confuse UIDeviceOrientation
and UIInterfaceOrientation
, they are different but related as shown by their declaration
typedef enum {
UIDeviceOrientationUnknown,
UIDeviceOrientationPortrait,
UIDeviceOrientationPortraitUpsideDown,
UIDeviceOrientationLandscapeLeft,
UIDeviceOrientationLandscapeRight,
UIDeviceOrientationFaceUp,
UIDeviceOrientationFaceDown
} UIDeviceOrientation;
typedef enum {
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait,
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown,
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight,
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
} UIInterfaceOrientation;
UIDeviceOrientation
tells you what the orientation of the device is. UIInterfaceOrientation
tells you what the orientation of your interface is, and is used by UIViewController
. UIInterfaceOrientation
will clearly be either portrait or landscape, whereas UIDeviceOrientation
can have ambiguous values (UIDeviceOrientationFaceUp
, UIDeviceOrientationFaceDown
, UIDeviceOrientationUnknown
).
In any case you should not attempt to determine the orientation of a UIViewController with [[UIDevice currentDevice] orientation]
, as no matter what the device orientation is the UIViewController interfaceOrientation
property can be different (for example if your app does not rotate to landscape at all [[UIDevice currentDevice] orientation]
can be UIDeviceOrientationLandscapeLeft
while viewController.interfaceOrientation
can be UIInterfaceOrientationPortrait
).
Update:
As of iOS 8.0, [UIViewController interfaceOrientation]
is deprecated. An alternative offered here is [[UIApplication sharedApplication] statusBarOrientation]
. This also returns UIInterfaceOrientation
.