What's the Difference between Interface Orientation and Device Orientation?
Both of them seems the same but what's the actual difference between them?
Interface Orientation can be anything, regardless of device orientation. Device Orientation is the actual physical orientation of the device you are holding, and this is not variable; it is what it is. If you are holding in Portrait, it is Portrait. But just because the device is in Portrait doesn't mean your interface is also in portrait. You may require your app to only provide landscape orientation, hence the interface orientation would be different than the device orientation.
Following description got from this site.
UIDeviceOrientation is a property of the UIDevice class, and there are these possible values:
UIDeviceOrientationUnknown - Can't be determined
UIDeviceOrientationPortrait - Home button facing down
UIDeviceOrientationPortraitUpsideDown - Home button facing up
UIDeviceOrientationLandscapeLeft - Home button facing right
UIDeviceOrientationLandscapeRight - Home button facing left
UIDeviceOrientationFaceUp - Device is flat, with screen facing up
UIDeviceOrientationFaceDown - Device is flat, with screen facing down
As for UIInterfaceOrientation, it is a property of UIApplication and only contains 4 possibilities which correspond to the orientation of the status bar:
UIInterfaceOrientationPortrait = UIDeviceOrientationPortrait
UIInterfaceOrientationPortraitUpsideDown = UIDeviceOrientationPortraitUpsideDown
UIInterfaceOrientationLandscapeLeft = UIDeviceOrientationLandscapeRight
UIInterfaceOrientationLandscapeRight = UIDeviceOrientationLandscapeLeft
(copied from docs)
For example, the device (the actual iPhone or iPod) could be in UIDeviceOrientationLandscapeRight but if your app doesn't support that, it (your app) might still be in UIInterfaceOrientationPortrait.
In addition, to get UIDeviceOrientation, you use [[UIDevice currentDevice] orientation], and to get UIInterfaceOrientation, you use [[UIApplication sharedApplication] statusBarOrientation]
More info
Related
I'm using GPUImage which has class for a preview image. The preview image has to be set to the screen orientation for it to output correctly. Therefore, I need to get the correct orientation on app launch. However, testing [UIDevice currentDevice].orientation in viewDidLoad or viewWillAppear always returns 0 (Unknown).
So I force the orientation like so in viewDidLoad:
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
and it works on the iPhone and iPad mini - when app is launched in landscape, the device detects that it isn't in Portrait and reorients itself to landscape. This then calls viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
and the correct output is set for GPUImage's preview.
However, in the larger iPad sizes, this does not occur. When the app is launched in Landscape, it thinks it's in Portrait and does not redraw to Landscape as it does in the iPad Mini or iPhone. No call is made to viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator. I know it's because iPad in Portrait or Landscape is considered the same orientation. Somehow I need the app to know it's in Landscape after it launches so it can call the rotation methods.
Any advice?
I have a project whose rootViewController is a UINavigationController, and in my project only the view controller loading a full screen UIWebView. I need to change its orientation.
I have finished fixing the issue, but there's some trouble: When a user is in the view controller with the web view in the landscape orientation then clicks the back button, the previous view controller is also in landscape orientation. I want it to be in portrait, however. Any ideas on how to do this?
If you can read Chinese, I found this page, thanks.
implement
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
for whatever viewcontroller you require to stay in portrait.
I have try many solution, but the correct answer with working solution is:
ios 8 and 9, no need to edit info.plist.
- (BOOL) shouldAutorotate {
return NO;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return (UIInterfaceOrientationPortrait | UIInterfaceOrientationPortraitUpsideDown);
}
possible orientation
UIInterfaceOrientationUnknown
The orientation of the device cannot be determined.
UIInterfaceOrientationPortrait
The device is in portrait mode, with the device held upright and the home button on the bottom.
UIInterfaceOrientationPortraitUpsideDown
The device is in portrait mode but upside down, with the device held upright and the home button at the top.
UIInterfaceOrientationLandscapeLeft
The device is in landscape mode, with the device held upright and the home button on the left side.
UIInterfaceOrientationLandscapeRight
The device is in landscape mode, with the device held upright and the home button on the right side.
I want my iPhone app to globally behave as if only the UIInterfaceOrientationPortrait was permitted.
But at the same time I want it to be aware of the physical orientation in order to react in a specific way, only within a limited area of the display.
How can I get this?
I did some tests using the self.interfaceOrientation iVar of the UIViewController, but that does not seem to work, because this variable does not change.
First, do [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]. Then register for UIDeviceOrientationDidChangeNotification. When you receive the notification, check [UIDevice currentDevice].orientation for the device's physical orientation.
You should definitely read the documentation for these APIs, because it contains some important warnings.
Also note that device orientation is returned as a UIDeviceOrientation, which is different than a UIInterfaceOrientation. Keep in mind this information from the UIInterfaceOrientation documentation:
You use these constants in the statusBarOrientation property and the setStatusBarOrientation:animated: method. Notice that UIDeviceOrientationLandscapeRight is assigned to UIInterfaceOrientationLandscapeLeft and UIDeviceOrientationLandscapeLeft is assigned to UIInterfaceOrientationLandscapeRight; the reason for this is that rotating the device requires rotating the content in the opposite direction.
How does one detect the correct orientation of the application on the first view? I need to know so I can either display a portrait image or landscape image as the background.
[[UIDevice currentDevice] orientation] doesn't work properly if the iPad is laid down flat on a surface.
statusBarOrientation doesn't seem to return the correct results for the very first view that is loaded. I tried getting the status bar orientation in the viewWillAppear and viewDidLoad and both returned Portrait even when in landscape.
I have confirmed that I have [self.window makeKeyAndVisible] in my AppDelegate.m in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions. This is only returning the incorrect status bar orientation on the first view controller.
Note: I have also tried the interfaceOrientation from the UIViewController, ad that still returns portrait no matter what.
Any ideas how to fix this?
EDIT:
I am using the [[UIDevice currentDevice] orientation] to detect if it is portrait or landscape but my issue is detecting what the view actually is if UIDevice returns an orientation of flat (non portrait or landscape).
Many applications have this issue. If the device is flat then any of the orientations is valid.
Your best bet is to use the [[UIDevice currentDevice] orientation] to know what the orientation is if possible for the cases where the orientation can be determined. But when it's flat, it'll just be whatever it was last.
How many times have you see people flick up their iPad to get the landscape orienation the right way around.
GOT IT!
I was able to do a work around by using
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
Even on view load this method is triggered if the orientation is not of UIInterfaceOrientationPortrait.
Even if the device is flat, it seems that there is a long enough delay for the orientation to correct itself and detect whether the UIView is in portrait or landscape mode.
EDIT:
When viewDidAppear is triggered by then, [self interfaceOrientation] has the correct value. So if you can wait until that method, you can also get it there.
The [[UIDevice currentDevice] orientation] method returns a number of orientations beyond the portrait and landscape orientation. I am well aware of checking to see if the orientation returned is "valid", unfortunately if the orientation returned is NOT "valid" when my app requires a specific orientation to determine which methods to run, I have no way of knowing which method is appropriate.
I have attempted a number of solutions to this, but for now the only thing I have been able to work out is to check to see if the orientation is LandscapeLeft or LandscapeRight and if it isn't I assume the screen is in portrait orientation. Unfortunately this isn't true when the device is face up and the screen is in landscape orientation.
I attempted to use the parent view controller's orientation:
parentController.interfaceOrientation;
Unfortunately it returned UIDeviceOrientationUnknown. I search SO and Google for someone else who has faced this problem. It seems silly to me that Apple would have anything but LandscapeLeft/Right and PortraitUp/Down for their orientations.
What I really need is the APPS orientation not the devices, since these are sometimes at odds. Any advice?
Have you tried using UIInterfaceOrientationPortrait/UIInterfaceOrientationLandscape? I usually have pretty good results using these methods:
if(UIInterfaceOrientationIsPortrait(viewController.interfaceOrientation)) {
//do portrait work
} else if(UIInterfaceOrientationIsLandscape(viewController.interfaceOrientation)){
//do landscape work
}
You might also try UIDeviceOrientationIsValidInterfaceOrientation.
These will only return the app's orientation, which may not be the same as the device's orientation.
If those don't work, you can also try:
[[UIApplication sharedApplication] statusBarOrientation]