Changing the orientation of the program interface does not work for iOS

So, I have a project where I need to force an orientation change when the user clicks a button. I demonstrated the problem with an example application on github .

@interface DefaultViewController () { UIInterfaceOrientation _preferredOrientation; } 

Some rotation processing bits

 - (BOOL)shouldAutorotate { return YES; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return _preferredOrientation; } 

And switch

 - (IBAction)toggleButtonPressed:(id)sender { _preferredOrientation = UIInterfaceOrientationIsPortrait(_preferredOrientation) ? UIInterfaceOrientationLandscapeRight : UIInterfaceOrientationPortrait; [self forceOrientationChange]; } - (void)forceOrientationChange { UIViewController *vc = [[UIViewController alloc] init]; [self presentViewController:vc animated:NO completion:nil]; [UIView animateWithDuration:.3 animations:^{ [vc dismissViewControllerAnimated:NO completion:nil]; } completion:nil]; } 

So this works fine, when you just press the toggle button, it changes orientation as expected. But when I start to change the actual orientation of the device, a problem arises.

Steps to reproduce the problem:

  1. Open application in portrait orientation
  2. Press the button to change the orientation to landscape orientation (saving the actual device in the portrait)
  3. Press the button again to make the rotation return to the portrait (keeping the image in the portrait)
  4. Turn the actual device into landscape without pressing a button

The result is that the view does not rotate to landscape, but in the status bar.

Forced orientation change issue

Any help would be greatly appreciated!

+3
source share
3 answers

I managed to fix this by adding the following line before submitting and firing the view controller:

 [UIViewController attemptRotationToDeviceOrientation]; 

It's hard to say exactly why this works. This call requests attempts to map interfaceOrientation to deviceOrientation by calling shouldAutorotateToInterfaceOrientation: and subsequent rotation methods if YES returned.

It seems that the device’s interface and orientation are out of sync due to the workaround required to orient the interface, despite the device’s orientation. However, in my opinion, this should not happen, since the workaround is still the legal use of the provided methods. This might be an Apple stack / orientation bug.

Full method:

 - (void)forceOrientationChange { UIViewController *vc = [[UIViewController alloc] init]; [UIViewController attemptRotationToDeviceOrientation]; /* Add this line */ [self presentViewController:vc animated:NO completion:nil]; [UIView animateWithDuration:.3 animations:^{ [vc dismissViewControllerAnimated:NO completion:nil]; } completion:nil]; } 
+5
source

When we talk about orientation, these are two things that fall into the picture:

Device Orientation Interface Orientation As soon as it is visible only in name, the device orientation indicates in which device orientation, and the interface orientation indicates in which orientation your application presents its interface.

Here's what you do, your application supports all orientation. You must have a mark on all orientations in the project.

Now, when you change the orientation of the device from portrait to landscape, when you set the Orientation interface in program mode in portrait mode, this is what happens. As the orientation of the device changes, the orientation of your status bar also changes. But since you have a limited interface for your application in portrait orientation, it does not change orientation.

Here is what you can do:

  • Uncheck the support for landscape orientation for your application and check if the problem is resolved.
  • Let me know what happened when you completed the first step :)
+1
source

Use this code:

 UIApplication *application = [UIApplication sharedApplication]; [application setStatusBarOrientation:UIDeviceOrientationLandscapeLeft animated:YES]; [[UIDevice currentDevice] setOrientation:UIDeviceOrientationLandscapeLeft]; [super updateViewConstraints]; [self.view updateConstraints]; 
0
source

All Articles