How to change the device orientation programmatically in iOS 6 [duplicate]
In iOS 5 we could change the device orientation programmatically like so:
[[UIDevice currentDevice] setOrientation:UIInterfaceOrientationLandscapeRight];
But in iOS 6 setOrientation
is deprecated, how may i change the device orientation programmatically in iOS 6?
Here are my "five cents", tested on iOS7 with ARC
[[UIDevice currentDevice] setValue:
[NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
forKey:@"orientation"];
This doesnt generate "leak" warning as performSelector will.
UIAlertView - with this code, when you open UIAlertView during view(will/Did)appear you will notice that all but this view is in portrait (apple, really?) I wasn't able to force the view to reorient but found that if you put slight delay before opening the UIAlertView then view has time to change orientation.
Note I'm releasing my app week commencing 12/09/2014 and I will update post if it will pass or fail.
I found out that the easiest way to force the device to change orientation is to present a new view controller (using presentViewController:animated:completion:
) where the new view controller specified a particular preferred orientation (by implementing the method -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
).
When a new view controller is presented, as expected, the orientation will change to the one preferred by the new view controller. So, simplest implementation (best practice?) will be to embed all functionality you needed in a specific orientation into a separate view controller, and present it as needed. The system will take care of changing the orientation for you.
Obviously this might not suit all use cases, but, fortunately the same trick is applicable to force the device to change orientation for existing view controller.
The trick is to present a new view controller with the specific preferred orientation that you needed, and then hide it immediately. This will cause the orientation to change temporary when the new view controller is presented. The best part is, when the new view controller is dismissed, the original (presenting) view controller's preferredInterfaceOrientationForPresentation
is queried again, you can specify the final orientation you want here.
One important thing to look out here is to also temporary disable auto rotation in the original view controller (when coming back from the newly presented-then-dismissed view controller), so that when user rotate their phone towards the new orientation, it does not triggered further auto rotation.
The following code should illustrate my point, my example forces rotation to portrait, just change accordingly if you want other orientation.
Assuming you have the original view controller named Original
, and a temporary view controller named ForcePortrait
@interface Original : UIViewController
{
BOOL orientationToPortrait; //should set to NO by default
}
@end
@implementation Original
- (UIInterfaceOrientation) preferredInterfaceOrientationForPresentation
{
if(orientationToPortrait)
{
//when we manually changed, show in Portrait
return UIInterfaceOrientationPortrait;
}
else
{
//before manual orientation change, we allow any orientation
return self.interfaceOrientation;
}
}
-(BOOL) shouldAutorotate
{
//we should 'lock' the rotation once we manually change it
return !orientationToPortrait;
}
-(void) changeOrientationToPortrait
{
//Sample method to change the orientation
//when called, will show (and hide) the temporary view
//Original.preferredInterfaceOrientationForPresentation will be called again after this method
//flag this to ensure that we tell system we prefer Portrait, whenever it asked again
orientationToPortrait = YES;
//presenting the following VC will cause the orientation to temporary change
//when the new VC is dismissed, system will ask what is our (Original) orientation preference again
ForcePortrait* forcePortrait = [[ForcePortrait alloc] init];
[self presentViewController:forcePortrait animated:NO completion:^{
[forcePortrait dismissViewControllerAnimated:NO completion:nil];
}];
}
@end
@interface ForcePortrait : UIViewController
@end
@implementation ForcePortrait
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}
@end
This does not answer how to change the device Orientation, but an additional information that might help you.
iOS 6 UI Interface Orientation - shouldAutorotateToInterfaceOrientation: Not Working
The method shouldAutorotateToInterfaceOrientation: is NOT supported in iOS 6. Its deprecated. Just in case if you are a newbie, who just stared working in cocoa, and wondering why is your view controller messed up in iOS 6 and perfect in iOS 5, just know that shouldAutorotateToInterfaceOrientation: is not supported anymore. Even though it may work well with Xcode 4 to 4.3 it will NOT work on Xcode 4.5.
Apple provides a new method to get this thing done, in a much cleaner fashion. You use supportedInterfaceOrientations instead. It returns all of the interface orientations that the view controller supports, a mask of interface orientation values.
UIInterfaceOrientationMask Enum:
These constants are mask bits for specifying a view controller’s supported interface orientations.
typedef enum {
UIInterfaceOrientationMaskPortrait = (1 << UIInterfaceOrientationPortrait),
UIInterfaceOrientationMaskLandscapeLeft = (1 << UIInterfaceOrientationLandscapeLeft),
UIInterfaceOrientationMaskLandscapeRight = (1 << UIInterfaceOrientationLandscapeRight),
UIInterfaceOrientationMaskPortraitUpsideDown = (1 << UIInterfaceOrientationPortraitUpsideDown),
UIInterfaceOrientationMaskLandscape =
(UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight),
UIInterfaceOrientationMaskAll =
(UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft |
UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskPortraitUpsideDown),
UIInterfaceOrientationMaskAllButUpsideDown =
(UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft |
UIInterfaceOrientationMaskLandscapeRight),
} UIInterfaceOrientationMask;
Using shouldAutorotateToInterfaceOrientation: method:
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return UIInterfaceOrientationIsLandscapeRight(toInterfaceOrientation);
}
Using supportedInterfaceOrientations method:
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskLandscapeRight;
}
These are the added methods to UIViewController regarding Orientation in iOS6
UIViewController preferredInterfaceOrientationForPresentation
UIViewController shouldAutorotate
UIViewController supportedInterfaceOrientations
Added methods to UIApplication regarding Orientation in iOS6
UIApplication supportedInterfaceOrientationsForWindow:
UIInterfaceOrientationMask