4

I think this question should've been asked a million times by now, but I still can't find an answer to this.

Here's my hierarchy: UINavigationController -> UIViewController 1 ->(push)-> UIViewController 2

UINavigationController: supports all possible orientation UIViewController 1: supports only portrait UIViewController 2: supports only landscape

How can I lock UIViewController 1 into portrait only and at the same time lock UIViewController 2 into landscape only? Is it even possible? So far what I see is that UIViewController 2 always takes the orientation of UIViewController 1.

Note, that this is for iOS 6 only.

Thanks!

icodebuster
  • 8,890
  • 7
  • 62
  • 65
ymotov
  • 1,449
  • 3
  • 17
  • 28
  • Try this It will work for you : http://stackoverflow.com/questions/12520030/how-to-force-a-uiviewcontroller-to-portait-orientation-in-ios-6 – yen May 04 '13 at 06:45
  • You can't find an answer because it can't be done. Despite all the answers below, what you are asking to do is simply not supported in iOS 6. iOS 6 allows response to user rotation of the device, but not forced rotation. The only way to *force* rotation in iOS 6 is to use a presented view controller, not a view controller pushed onto the navigation controller stack. – matt May 04 '13 at 15:39
  • You can, however, construct a presented view controller in such a way that it *looks* as if it were part of the same navigation interface. And since a presented view controller *can* force rotation both when presenting and dismissing, this effectively solves the problem. See, for example, my answer here: http://stackoverflow.com/a/4103137/341994 – matt May 04 '13 at 15:42
  • 1
    I have made a movie showing what I mean: http://youtu.be/O76d6FhPXlE As you can see, it sort of *looks* like I'm pushing a second view onto the navigation controller and forcing rotation. But in reality there are *two* navigation controllers; the second one is presented (modal), so I am able to force rotation when it appears and when it is dismissed. – matt May 04 '13 at 22:07
  • Thanks @matt. That totally explains why everything I tried so far just doesn't work. Especially huge thank you for the your effort explaining in details and even creating a short movie. Super helpful!! Since I can't mark your comment as accepted answer I just up-voted your comment. – ymotov May 05 '13 at 01:23

3 Answers3

13

I am also find the same problem.i have found that shouldAutorotate function not call every time so i change orientation programmatic

first import this

#import <objc/message.h>

then

-(void)viewDidAppear:(BOOL)animated
{

     if(UIDeviceOrientationIsPortrait(self.interfaceOrientation)){
        if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)])
        {
            objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationLandscapeLeft );


        }
    }

}

hope this help you.

Sumit Mundra
  • 3,891
  • 16
  • 29
  • setOrientation is an undocumented method, using it can be cause for dismissal of your app from the AppStore. Use at your own risk. – Martin Aug 31 '13 at 03:32
  • no its not true. I am also use this method in my app and this is live on app store. – Sumit Mundra Aug 31 '13 at 05:14
  • Apple used to have a public read write property for orientation available. They changed it to read only. The above is a dangerous trick providing you access to their private setter. This very well can lead to your app being rejected. In your case it didn't, but use this at your own risk. – TheCodingArt Sep 08 '13 at 04:11
  • Finally! Thank you! Clear and simple! – skywinder Dec 17 '13 at 00:53
  • that causes the rotation of the interface as you want, but don't forget to switch back right after or else device will think it's in wrong orientation by adding this right in the second line: `objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), _yourRealInterfaceOrientation );` – user726522 Dec 19 '13 at 11:01
9

Add new Objective-C class (subclass of UINavigationController) and add the following code to the .m files

-(NSUInteger)supportedInterfaceOrientations
 {
     NSLog(@"supportedInterfaceOrientations = %d ", [self.topViewController         supportedInterfaceOrientations]);

     return [self.topViewController supportedInterfaceOrientations];
 }

-(BOOL)shouldAutorotate
  {
     return self.topViewController.shouldAutorotate;
  }

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
  {
    // You do not need this method if you are not supporting earlier iOS Versions

    return [self.topViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
  }

After you added the new classes go to your ViewController classes and make the following changes

- (BOOL)shouldAutorotate  // iOS 6 autorotation fix
  {
    return YES;
  }
- (NSUInteger)supportedInterfaceOrientations // iOS 6 autorotation fix
  {
      return UIInterfaceOrientationMaskAll;
  }

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation // iOS 6 autorotation fix
  {
      return UIInterfaceOrientationPortrait;
  }
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
  {
      return YES;
  }

enter image description here

In the shouldAutorotate , shouldAutorotateToInterfaceOrientation: return YES if you want the ViewController to be supporting Multiple orientation else return NO , also in houldAutorotateToInterfaceOrientation: method pass the Orintation you want for that specific ViewController , Repeat the same for all the view controllers .

Reason of doing this:-

1:Although you can change the preferredInterfaceOrientationForPresentation: of any viewController to a specific orientation but since you are using the UINavigationController you also need to override the supportedInterfaceOrientations for your UINavigationController

2:In order the override the supportedInterfaceOrientations for UINavigationController we have subclassed UINavigationController and modified the method related to the UINavigation Orientation.

Hope it will help you !

Gaurav Rastogi
  • 2,145
  • 1
  • 14
  • 19
1

Make the app support only portrait mode and add the following line to the initWithNibName of UIViewController 2

self.view.transform = CGAffineTransformMakeRotation(M_PI/2);