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"]; 

4 Answers4

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.

Santu C
  • 2,644
  • 2
  • 12
  • 20
  • 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. –  May 21 '15 at 09:48
  • Incase of you want to restrict LandScapeViewControler only to LandScape mode. Otherwise you can return YES – Santu C May 21 '15 at 10:06
  • 2
    unfortunately, my **shouldAutorotate** is not being called .you know why? –  May 21 '15 at 10:11
  • Please check this link http://stackoverflow.com/questions/12775265/ios-6-shouldautorotate-is-not-being-called – Santu C May 21 '15 at 10:25
  • thanks got.it .from http://stackoverflow.com/questions/12260261/shouldautorotatetointerfaceorientation-not-being-called-in-ios-6 –  May 21 '15 at 10:38
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?

Community
  • 1
  • 1
Mika
  • 5,807
  • 6
  • 38
  • 83
  • I dont need landscape for my app except photos and videos. Including "landscape to the deployment" make no sense. –  May 21 '15 at 09:27
  • 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 Landscape – Mika May 21 '15 at 09:28
  • 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** ? –  May 21 '15 at 09:41
  • 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. – Mika May 21 '15 at 09:49
  • 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 :( @Mikael –  May 21 '15 at 09:58
  • You can use landscape views even though you have set on portrait in project settings. You do not need to set landscape mode. – mkeremkeskin May 21 '15 at 09:59
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];
mkeremkeskin
  • 644
  • 10
  • 27
0

Updated answer for Swift 3+:

let value = UIInterfaceOrientation.landscapeLeft.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
Antoine
  • 23,526
  • 11
  • 88
  • 94
  • 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. – Jonny Feb 02 '18 at 08:16