iPad device orientation always wrong when flat - ipad

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)...

Related

IOS Simulator rotates despite Info.plist [duplicate]

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>

Get "locked orientation", also known as "view orientation"

I have locked the orientation via XCode to be either landscape-left and landscape-right, but using UIDevice.current.orientation is giving the orientation as if it was not locked. Like when I am physically (in real life) in portrait, but my view is locked in landscape-left, I want to still get landscape-left, is this possible?
I can of course get the non-specific orientation by testing if width > height. But i needed the specific orientation of either landscape-left or -right.
Instead of asking the device for its orientation, ask the app for its orientation, by asking for UIApplication.shared.statusBarOrientation.

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.

Starting iPad app in current landscape orientation

My ipad app only runs in landscape orientation. But when I test on an actual device (not the simulator) it always seem to start in one particular landscape orientation, then turn 180 degrees to match the current physical landscape orientation. So, it seems to start in LandscapeLeft(I think) then rotate 180 if I have it in LandscapeRight. There's nothing in Info.plist to set the initial orientation.
Can anyone suggest a way to detect current orientation before view loads and set it to correct landscape view before showing?
Thanks
Fitto
There is the UIInterfaceOrientation~iPad key which sets the initial interface orientation on startup.
There is also the UISupportedInterfaceOrientations key which informs the app which orientations are supported.
There is no way, however, to make the app start in the current orientation of the iPad.
Have you looked into these questions?
Get current orientation of iPad?
iPad launch orientation
Also, technically, the iPad should just do it. Make sure you have supported orientations set properly, as I'm sure it checks those to see where it should start.

Resources