How to manually set the device orientation when App Deployment Info portrait is locked?
Asked Answered
H

4

5

I dont want my app to be landscaped and always be porttrait.So i made my app Deployment Info to set portrait only. but when i need to display any image or videos in my app,i need landscape mode for better display.

I can detect the device orientation change by

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(orientationChanged:)
 name:UIDeviceOrientationDidChangeNotification
 object:[UIDevice currentDevice]];

- (void) orientationChanged:(NSNotification *)note
{
UIDevice * device = note.object;
switch(device.orientation)
{
    case UIDeviceOrientationPortrait:
        /*  */
        break;

    case UIDeviceOrientationPortraitUpsideDown:
        /*  */
        break;
    case UIDeviceOrientationLandscapeLeft:
       /*  */
       break;

    case UIDeviceOrientationLandscapeRight:
       /*  */
       break;
    default:
        break;
};
}

But how do i manually change my device orientation even when App Deployment Info portrait is locked ?

This doesnt worked

NSNumber *value=[NSNumber numberWithInt: UIDeviceOrientationLandscapeLeft];
[[UIDevice currentDevice] setValue:value forKey:@"orientation"]; 
Hollingshead answered 21/5, 2015 at 9:11 Comment(0)
G
8

Please enable Portrait & Landscape from your project setting. Then use below method for all viewcontroller to autorotation turn off -

- (BOOL)shouldAutorotate {
    return NO;
}

Then use below method to all except LandScapeViewControler -

- (void)viewWillAppear:(BOOL)animated {

    [[UIDevice currentDevice] setValue:
     [NSNumber numberWithInteger: UIInterfaceOrientationPortrait]
                                forKey:@"orientation"];
}

Use below method for LandScapeViewControler -

- (void)viewWillAppear:(BOOL)animated {

        [[UIDevice currentDevice] setValue:
         [NSNumber numberWithInteger: UIInterfaceOrientationLandscapeLeft]
                                    forKey:@"orientation"];
    }

If you are using NavigationController and TabBarController then please use category to turn off autorotation .

Hope this will be help you.

Grinnell answered 21/5, 2015 at 9:32 Comment(5)
why do need this method LandScapeViewControler--- (void)viewWillAppear:(BOOL)animated ? can't i just put shouldAutorotate to YES in LandScapeViewControler and it can rotate to LandScapeleft,right,portrait,upsidedown.Hollingshead
Incase of you want to restrict LandScapeViewControler only to LandScape mode. Otherwise you can return YESGrinnell
unfortunately, my shouldAutorotate is not being called .you know why?Hollingshead
Please check this link #12775765Grinnell
thanks got.it .from #12260761Hollingshead
A
6

Two steps:

  1. Include landscape to the deployment
  2. In each view controller viewDidLoad you need to include:

    //Swift
    let value = UIInterfaceOrientation.LandscapeLeft.rawValue
    UIDevice.currentDevice().setValue(value, forKey: "orientation")
    
    //Obj-C
    NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft];
    [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
    

See also: How do I programmatically set device orientation in iOS7?

Alexina answered 21/5, 2015 at 9:17 Comment(6)
I dont need landscape for my app except photos and videos. Including "landscape to the deployment" make no sense.Hollingshead
If you have any scenario where you do you can't prevent it entirely. Presumably videos and Images are displayed in a view controller so only set that one to LandscapeAlexina
im using a QLPreviewController to view files and you deviated from my question "How to set orientation even portrait lock in Deployment Info is ON ?Hollingshead
If you set it in the deployment info your target will not support the unchecked options. So what I am telling you is that you can't do it the way you are trying to do it.Alexina
got your point.and im trying to 1.check portrait and landscape in deployment info 2.- (BOOL)shouldAutorotate { return NO; } in all views except landscape view and forcing portrait default in viewdidload of all views except landscape. but this too didnt work :( @MikaelHollingshead
You can use landscape views even though you have set on portrait in project settings. You do not need to set landscape mode.Schoolman
S
3

Instead of forcing orientation change you should subclass a navigation controller which is landscape and use it by presenting. Then your app would always be portrait as you want it. It will landscape when you use this navigation controller.

#import "RotationAwareNavigationController.h"

@implementation RotationAwareNavigationController

-(BOOL)shouldAutorotate {
    return NO;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeRight;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}

You should call it like below;

RotationAwareNavigationController *navController = [[RotationAwareNavigationController alloc] initWithRootViewController:aViewController];
[self presentViewController:navController animated:NO completion:nil];
Schoolman answered 21/5, 2015 at 9:21 Comment(0)
G
0

Updated answer for Swift 3+:

let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
Glycol answered 21/7, 2017 at 7:55 Comment(1)
Mostly working, but got a few (2) crashes with this during testing. I guess not a big issue; but still this is obviously an "undocumented" feature and should be treated as such. I will look for another way.Sansculotte

© 2022 - 2024 — McMap. All rights reserved.