IOS Simulator rotates despite Info.plist [duplicate] - ios

I am updating an old iPad app, but I'm unable to stop iOS from rotating a controller that should only be viewed in portrait mode. The app has a UISplitViewController, but at one point I need to present another controller fullscreen in portrait mode regardless of whether the iPad was in portrait or landscape before.
I have two issues:
If the UI was in landscape mode, the portrait view controller also appears in landscape
The rotation is no longer blocked, so the user can rotate the device even if the controller was displayed in the correct orientation
The documentation says that all rotation-related methods were deprecated in iOS 8, and instead iOS will call viewWillTransitionToSize on the window's root viewcontroller. I am therefore calling [window setRootViewController] to setup my portrait-only controller, and indeed iOS calls viewWillTransitionToSize on my controller. However, at that point it's already too late! I need to stop the transition before it begins.
After spending many hours googling and trying variations, I am no closer to a solution – there is so much old stuff on the 'net (and here on Stack Overflow) that it's really hard to find current information.
I have tried setting modalPresentationStyle = UIModalPresentationFullScreen both in viewDidLoad, viewWillAppear and viewDidAppear, and then overriding preferredInterfaceOrientationForPresentation. My override is never called.
I still have the old methods supportedInterfaceOrientations, shouldAutorotate and shouldAutorotateToInterfaceOrientation, but none of them is ever called.
I tried implementing application:supportedInterfaceOrientationsForWindow in my app delegate, but the method is never called. (from the answers to this question)
What's the correct way of doing this on iOS 14? Should I use a modal full-screen presentation? Or use the trait environment with UITraitCollection somehow?

You cannot by any means prevent an iPad app that can assume all four rotational position from actually assuming all four rotational positions, unless you explicitly opt out of iPad multitasking.
To do so, set the Info.plist key UIRequiresFullScreen to YES; you can do that conveniently while editing the app target by checking Requires Full Screen in the General tab.
But Apple warns that this option is slated to be removed; multitasking will become a requirement and thus rotation to any position will be required as well. Basically it would be better to change your desires.

I had asked a simmilar Question for an Ipad but i got closed because of this Question.
My Solution for Ipad IOS 14.5 and VisualStudio2019 was adding these Lines in the InfoPlist.
(For beginners Like me: don't open the Manifest Mask, rightclick the "infoPlist" unter the IOS Header and select "view Code".) Then add these Missing lines:
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string> <!--For Vertikal-->
<string>UIInterfaceOrientationLandscapeLeft</string> <!--For Horizontal-->
<string>UIInterfaceOrientationLandscapeRight</string> <!--For Horizontal-->
</array>

Related

Force Rotate iOS Even When Device's Portrait Orientation Lock is ON

My app needs to somehow mimic the iOS original Camera App, that even the device's AUTOROTATE is locked, the ViewController or specifically the AVCaptureVideoPreviewLayer will rotate.
So far, what I did to my project is this: Check the Landscape (right and left) in Project Properties/Settings, and then tweak each View Controllers' shouldAutorotate.
Everything is fine using this technique, until the user lock his device autorotate function (in iPAD this is a button at the side of the device, in iPhone this can be found in the settings from below the screen).
I couldn't find any answered related question on stackoverflow, so I asked.
So after few days, I have solved the problem!!! I'm still wondering though what was the reason behind in down voting my question. I have found this tutorial/blog:
Detect Device Rotation Even When Rotation Lock Is ON
So basically, the alternative way is to use CoreMotion. I hope someone who is having the same question in mind finds this answer. Cheers!

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.

Landscape-only IPad App With UISplitViewController

I am almost done developing an app. Right now I'm converting it to a universal app by supporting iPad to supported devices as well.
Can I set the app to use Landscape orientation only, since I am using UISplitViewController and want the Master View Controller to remain on the screen all the time? Is there any Apple policy that states that I cannot restrict it to Landscape only and I have to implement both portrait and landscape? Is there any chance my app can be rejected by setting it to Landscape only for iPad?
Don't worry, you'll be fine. Support both landscape orientations and neither portrait orientation if you want. I've got apps in the store that are like that.
However, note that UISplitViewController does have an option to keep both views on the screen all the time even in portrait. Use the delegate method splitViewController:shouldHideViewController:inOrientation: to forbid hiding the master view:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UISplitViewControllerDelegate_protocol/Reference/Reference.html#//apple_ref/occ/intf/UISplitViewControllerDelegate
So if your only reason for being landscape only is that you don't want to hide the master view, it is a false reason. Look, for example, at Apple's Settings app, which works like that; it is a split view controller that always shows both views in all four orientations.

iOS application won't rotate on iPhone but will rotate on iPad

I made my gles app, and tested it on my iPad. It is supposed to work only on landscape mode, so I have my Info.plist like this
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
I set landscape-right only for iPhone so the splash screen shows correctly (it seems you can't set separate splash screens for landscape-right and landscape-left on the iPhone)
The application runs fine, but on a friend's iPhone, the app runs on portrait mode, and won't rotate to either landscape. The rotation lock is off.
I am not doing anything in particular from my code to support rotations, as just setting my Info.plist worked perfectly on my iPad.
The iPhone simulator automatically turns to landscape, and retains the landscape rendering even if I rotate it.
What could be causing this? I also tried allowing both landscape rotations, but no dice.
ios6 introduced new ways to deal with orientation changes - I'd guess your friend's iphone is running ios5. See the UIViewController docs to see how to deal with both versions:
Handling View Rotations
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.
In iOS 5 and earlier, the UIViewController class displays views in
portrait mode only. To support additional orientations, you must
override the shouldAutorotateToInterfaceOrientation: method and return
YES for any orientations your subclass supports. If the autoresizing
properties of your views are configured correctly, that may be all you
have to do. However, the UIViewController class provides additional
hooks for you to implement additional behaviors as needed. Generally,
if your view controller is intended to be used as a child view
controller, it should support all interface orientations.
When a rotation occurs for a visible view controller, the
willRotateToInterfaceOrientation:duration:,
willAnimateRotationToInterfaceOrientation:duration:, and
didRotateFromInterfaceOrientation: methods are called during the
rotation. The viewWillLayoutSubviews method is also called after the
view is resized and positioned by its parent. If a view controller is
not visible when an orientation change occurs, then the rotation
methods are never called. However, the viewWillLayoutSubviews method
is called when the view becomes visible. Your implementation of this
method can call the statusBarOrientation method to determine the
device orientation.

iPad device orientation always wrong when flat

I know this subject gets a lot of attention here at SO, but none of the "solutions" is working for me. Here's the situation:
iPad is flat on my desk (a face up device orientation), the home screen is perfectly readable, but the home button is on top. So this is effectively shows a "Portrait Up Side Down" interface orientation.
I start my app
The app calls beginGeneratingDeviceOrientationNotifications to make sure the accelerometer is working, and the orientation notifications come in.
At startup, my app queries both the "interface orientation" and the "device orientation". The results are:
STARTUP ORIENTATION:
INTERFACE ORIENTATION: UIInterfaceOrientationPortrait
DEVICE ORIENTATION: UIDeviceOrientationFaceUp
The Apple docs say that each app (interface?) starts in portrait orientation, so this could make sense. The device orientation is also correct, because this is indeed face up.
Right after launching, the first orientation notification is coming in:
NOTIFICATION 1:
INTERFACE: UIInterfaceOrientationPortrait
DEVICE: UIDeviceOrientationPortrait
Again, portrait for the interface, (which is contrary to what I'd expect, the home screen showed itself in up side down orientation), the device is said to be in portrait too (which isn't so, but this is apparantly a clever scheme to work out how to orient your app's contents when the device is face up or down).
As many people mention, another (just one, not two) orientation notification follows:
NOTIFICATION 2:
INTERFACE: UIInterfaceOrientationPortrait
DEVICE: UIDeviceOrientationFaceUp
Still portrait (and not up side down) for the interface, and back to face up for the device (which is correct).
My app adjusts itself correctly, and is shown up side down, which is totally wrong.
What can I do to know the last known orientation, the one's that's shown in the home screen and other UI on the iPad?
This is an OpenGL app with just a window and a view. I've already added a UIViewController to the mix to see if this gives more accurate information, but it's just the same, and wrong. I know I'm not the only dev struggling with this, because many apps I have on my iPad do it wrong too, you have to tilt the device to make them orient themselves properly. But some apps do seem to get it right, what's the secret?
Okay, I'm not happy to have to admit that I did overlook an essential piece in the maze that is iOS device/interface orientations: the UISupportedInterfaceOrientations property in your app's Info.plist file.
I read about it and (wrongly) assumed that by specifying the supported orientations, the behavior wouldn't change. But as it turns out, it's not just a filter on the orientation notifications (it isn't, you still get notifications for unsupported orienations), but the type/order of notifications is different depending on how the device is oriented.
In my case, I wasn't interested in the "face up" and "face down" orientations, so I just ignored them. This is not a good idea. If you specify the supported orientations explicitly:
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
...then you will still see the behavior as I describe in the comments above:
"Essentially, the device is pretending the user really quickly shook it back to an upright position, and back down."
...but the first passed orientation isn't always portrait, but the correct orientation instead.
So, in the scenario I describe in my question, the device orientations would be as follows:
AT STARTUP: UIDeviceOrientationFaceUp
NOTIFICATION 1: UIDeviceOrientationPortraitUpsideDown <-- CORRECT!
NOTIFICATION 2: UIDeviceOrientationFaceUp <-- CORRECT, BUT IGNORE
I wouldn't want to go as far and call this a bug on Apple's part, but it's unclear to me why the passed orientation in NOTIFICATION 1 is always portrait when you don't specify UISupportedInterfaceOrientations.
Note that this only applies to the iPad. The home screen UI on iPod Touch and iPhone are always in portrait, so it's easier to know what that orientation was at launch (you guessed it: portrait)...

Resources