Device Orientation iOS - ios

I want to have my app always in portrait mode facing up. That means that if the device it tipped to passed perpendicular to the floor and is starting to face the floor, it will readjust so it functions like it is in portrait mode facing upward. The same with if the device starts to be portrait upside-down, it will be portrait facing up (tilted upward. I have placed this in my apps delegate
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
under the -(BOOL) application did finishLaunching etc. but I need to know what I need to put into the delegate so throughout the app the above is always true.
Anyone help.

You specifying all required orientations in your Info.plist file as Array with a key UISupportedInterfaceOrientations Limit the list of supported orientation to the orientation that you want. beginGeneratingDeviceOrientationNotifications is very specific method that required for a unique use-cases but not for general orientation handling. Here is some of examples where beginGeneratingDeviceOrientationNotifications could be useful, but it is definitely not your case - How to handle autorotation in AVCaptureVideoPreviewLayer?

You can set this in your project's deployment info in Xcode.
I think you also need to implement shouldAutorotate and supportedInterfaceOrientations in your UIViewControllers. This Apple reference doc should help: UIViewController Class Reference.
Also, here's a similar question and answer.

Related

Initial Interface Orientation to Landscape iOS 9

Technical Note TN2244: Launching your iPhone Application in Landscape states:
The values of the UISupportedInterfaceOrientations key determine how the status bar is positioned while the the app is launching. In iOS 7 and below, if the UIInterfaceOrientationPortrait value is present, the status bar will always be positioned for portrait orientation. Otherwise, the status bar will be positioned according to the first orientation that appears under the UISupportedInterfaceOrientations key.
So in iOS 8 it was perfectly fine to put UIInterfaceOrientationLandscape first in the UISupportedInterfaceOrientations list to have your app to start in Landscape.
It does not work anymore in iOS 9. Having UIInterfaceOrientationPortrait in the list at any position forces app to start in Portrait.
Question
Is there a known workaround for this? I need my app to start in Landscape.
Note: Using viewControllers' supportedInterfaceOrientations() method is not an option as it takes effect after the LaunchScreen is presented.
Having UIInterfaceOrientationPortrait in the list at any position forces app to start in Portrait.
That is absolutely correct — very good detective work. It took me a lot of experimentation to figure this out! This is certainly a huge change from iOS 8. You have summed up the situation very well.
Fortunately, the workaround is simple. In your Info.plist, include only the two landscape orientations. Now the app will launch into whichever one is first.
Now implement application:supportedInterfaceOrientationsForWindow: in the app delegate to return All. That way, when the time comes to show a portrait view controller, it will be legal to do so.
In other words, think of the Info.plist as what the launching app needs to know, and application:supportedInterfaceOrientationsForWindow: as what the running app needs to know.

iphone keyboard is rotating into landscape while app setting is portrait only

My app’s device orientation is set to portrait, however when rotating the device into landscape mode, the app is keeping its portait mode but the keyboard is rotating into landscape mode...Something that is unexpected.
Why is that happening and how to prevent it?
Thanks
Jrejory
After not getting any answer and making more researches, I came across this Answer:
https://stackoverflow.com/a/6941930/4400274
Because I just needed the portrait orientation in my app the following worked for me :
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
I put that in my main Navigation Controller's viewDidLoad.
I know it's late. But maybe it will help someone else. I had the similar issue. My app should support portrait orientation for iPhone and all orientations for iPad. So, on the iPhone scene didn't rotate, but keyboard did. All my UI was made from code, I also init view controllers (including root) through code. But I didn't remove default Main.storyboard file. When I removed string in Target -> General -> Main Interface, it help me. It was not obvious.

Forcing Portrait Mode in a UIPageViewController on iPad

I have an iPad app which supports Portrait and Landscape in the entire app. This is an iOS 7 and iOS 8 version of an app.
The app is a UITableViewController with multiple segues to a different set of UIViewControllers. I have one option in the app to show the Tutorial again and I have created the images in a Portrait mode only orientation because it just wouldn't make too much sense (or look good in Landscape).
With this in mind, the tutorial is in the form of images loaded into a UIPageViewController. The images are loaded in the viewDidLoad and the buttons and layout work really well.
Issue
I want to restrict the UIPageViewController to be in a Portrait orientation only.
Currently, I have:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[[UIDevice currentDevice] setValue:
[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
forKey:#"orientation"];
}
That works to some extent. If the device is in Landscape mode and the tutorial is invoked, it rotates it to Portrait.
However, if the device is in Portrait and I rotate it to Landscape after invoking the Tutorial, the tutorial then rotates.
How exactly do I prevent this view from rotating in my custom UIPageViewController class, so that it never rotates to Landscape whether it's at the start, middle, or end of the tutorial.
Any guidance on this would really be appreciated.
Take a look at UIViewController docs for Orientation support, specifically shouldAutorotate: and supportedInterfaceOrientations- https://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/instm/UIViewController/supportedInterfaceOrientations
My first guess would be you would want to set the value like you're doing now, and then override shouldAutorotate in your custom UIPageViewController subclass and return NO.
However, be aware you could get hit in the review process for HIG compliance, because your app claims to support all orientations, but parts of it don't. Obviously this is totally up to the reviewer and whether or not they catch it as plenty of other apps do this.

iOS - UISupportedInterfaceOrientations and shouldAutorotateToInterfaceOrientation

I am looking for some clarification on how to allow only certain orientations for your iOS app. I am aware of UISupportedInterfaceOrientations and shouldAutorotateToInterfaceOrientation but I am a little confused on their uses and exactly how they fit together.
I attempted to use UISupportedInterfaceOrientations to only allow landscape orientations, which appeared to have no affect until I researched in to it and read that it affects the initial orientation. Upon testing this, my app does appear to only open in landscape but quickly rotates if the screen is portrait.
I know you can use shouldAutorotateToInterfaceOrientation to limit the allowed orientations, for example:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
However, while doing some reading online I read shouldAutorotateToInterfaceOrientation is deprecated as of iOS6.
Basically my questions are:
What is the correct approach for limiting screen orientations across
multiple versions of iOS?
Is the only use of UISupportedInterfaceOrientations to limit the
initial orientation?
Edit:
To expand on the accepted answer, shouldAutorotate works in iOS6. As a quick fix if you've already implemented your logic in shouldAutorotateToInterfaceOrientation and/or you want to support earlier versions of iOS, you can do the following:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft) ||
(interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
- (BOOL)shouldAutorotate {
return [self shouldAutorotateToInterfaceOrientation:self.interfaceOrientation];
}
The method you need to use for rotation instead of shouldAutorotateToInterfaceOrientation is just shouldAutorotate
Handling rotation, according to the AppleDoc for ViewControllers:
In iOS 6, your app supports the interface orientations defined in your app’s Info.plist file. A view controller can override the supportedInterfaceOrientations method to limit the list of supported orientations. Generally, the system calls this method only on the root view controller of the window or a view controller presented to fill the entire screen; child view controllers use the portion of the window provided for them by their parent view controller and no longer participate in directly in decisions about what rotations are supported. The intersection of the app’s orientation mask and the view controller’s orientation mask is used to determine which orientations a view controller can be rotated into.
You can override the preferredInterfaceOrientationForPresentation for a view controller that is intended to be presented full screen in a specific orientation.
The method shouldAutorotateToInterfaceOrientation is deprecated, as are some methods for handling responses to device rotation.
For supporting methods of multiple versions of iOS, Here's something else that Apple has said:
For compatibility, view controllers that still implement the shouldAutorotateToInterfaceOrientation: method do not get the new autorotation behaviors. (In other words, they do not fall back to using the app, app delegate, or Info.plist file to determine the supported orientations.) Instead, the shouldAutorotateToInterfaceOrientation: method is used to synthesize the information that would be returned by the supportedInterfaceOrientations method.
Taken from release notes
To answer your second question:
Yes, the "UISupportedInterfaceOrientations" entry in the Info.plist is used only for initial startup of your app, making sure it doesn't start your app in an orientation it doesn't support, so that it's not required to perform a rotation right away.
Also, overriding "application:supportedInterfaceOrientationsForWindow" in your AppDelegate is pretty useful if your app never wants to use particular orientations (e.g. for a game that only does landscape).
Lastly, and this is a common error, on iPhone and iPod Touch devices, the device should never rotate to UIInterfaceOrientationPortraitUpsideDown! That's because these devices (contrary to an iPad) do not let the user lock a device in landscape mode with the Lock soft button - that button only locks into portrait. Therefore, if a user, laying on his side, wants to use an app in landscape mode, he cannot do this if your app goes into the upside down orientation. But if you disallow that rotation, then it works.

shouldAutorotateToInterfaceOrientation return YES

I often see code like this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return YES;
}
If the supported orientation is set in the project configuration, wouldn't just returning YES all the time be pointless? Or are there certain cases where this has an effect?
shouldAutorotateToInterfaceOrientation: (which is deprecated since iOS 6, by the way) is something completely different than the UISupportedInterfaceOrientations in the info plist! If you don't implement this method, the respective view controller won't ever autorotate to that interface orientation, no matter what you specify in UISupportedInterfaceOrientations.
From the documentation of UISupportedInterfaceOrientations:
The system uses this information (along with the current device orientation) to choose the initial orientation in which to launch your app.
Maybe in many parts of your application you support multiple interface orientations, but in one part you only support some of them (for example you want a video only to play in landscape)
So even if your app supports portrait, you probably want that the viewcontroller makes the orientation landscape
Edit: i'm commenting here because I can't comment other answers.
#daniel-rinser in iOS6, the system checks for project supported interface orientations, and intersects with viewcontroller's supported orientations, so it isn't only for launch but for all app execution.

Resources