30

App Support: iOS6+

My app works in both portrait and landscape. But 1 controller should only works in a Portrait.

The problem is that when I am in landscape and push the view controller the new viewcontroller is in landscape as well until I rotate it to portrait. Then it's stuck in portrait as it should be.

Is it possible to always make it appear in portrait? Even if its parent is pushing it in landscape?

All the following code doesn't help

[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];

And this code works until and unless i am not pushing from landscape How to force a UIViewController to Portrait orientation in iOS 6

Community
  • 1
  • 1
Tariq
  • 9,861
  • 12
  • 62
  • 103

2 Answers2

31

I solved this by adding following lines in ViewDidLoad

UIViewController *c = [[UIViewController alloc]init];
[self presentViewController:c animated:NO completion:nil];
[self dismissViewControllerAnimated:NO completion:nil];
Tariq
  • 9,861
  • 12
  • 62
  • 103
  • 1
    +1: I needed to "force" the orientation of a viewcontroller before it appeared, and this did the trick. Wish I knew the "official" method to force orientation, but until I do, I'll use this method. – brainjam Apr 24 '13 at 21:54
  • 2
    If you're going to be calling the view more than once, I suggest that add those lines to the viewWillAppear. – ChavirA May 27 '13 at 19:22
  • But this API is deprecated since iOS6... :/ – Serzhas Mar 05 '14 at 18:44
  • 2
    it does not work on Ipad when i implement this solution a black screen comes in. – Suleman Ilyas Apr 17 '14 at 06:46
  • it pushes the viewcontroller in potrait mode but then black screen appears on top of it ? how to get rid of that blackscreen please let me know – hariszaman Aug 28 '14 at 12:04
  • 3
    Has anyone found a solution for this on iOS 8? This hack no longer works, as mentioned above. Does Apple seriously not have any way of dealing with this in iOS 8? – mnemia Sep 25 '14 at 19:39
  • @Tariq: Did anyone figure out how to achieve this in iOS 8? It's not working as expected in iOS 8. Please help me doing this in iOS 8. – Rashmi Ranjan mallick Oct 13 '14 at 13:04
  • Sorry everyone. I'll investigate the issue and will post the solution. – Tariq Oct 13 '14 at 18:09
  • @Tariq Yes its working fine during pusing time but not working on pop time. it crashing. please help me out on this. – Hitarth Nov 12 '14 at 12:15
  • Had to change to `[c dismissViewControllerAnimated:NO completion:nil];` but still works in ios 9! – jrhee17 May 30 '16 at 05:36
3

First, you need to create a category:

UINavigationController+Rotation_IOS6.h

#import <UIKit/UIKit.h>

@interface UINavigationController (Rotation_IOS6)

@end

UINavigationController+Rotation_IOS6.m:

#import "UINavigationController+Rotation_IOS6.h"

@implementation UINavigationController (Rotation_IOS6)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

@end

Then, you implement these methods in your class that you want to be only landscape:

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscape;
}

In case you're using a UITabBarController, just replace the UINavigationController for UITabBarController. This solution worked nice for me after a long search! I was in the same situation as you are now!

EDIT

So, I saw your sample. You need to make some changes. 1 - Create a new class for the UINavigationController category. Name the class UINavigationController+Rotation_IOS6 (.h and .m) 2 - You don't need to implement the method preferredInterfaceOrientationForPresentation. Your category should look like this:

#import "UINavigationController+Rotation_IOS6.h"

@implementation UINavigationController (Rotation_IOS6)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

@end

3 - In the class you want to rotate only in landscape, include this in the implementation, exactly like this:

// Rotation methods for iOS 6
- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskLandscape;
}

4 - I would advice to also include the method for autorotation for iOS 5 inside the class you want in landscape:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return UIInterfaceOrientationLandscapeLeft | UIInterfaceOrientationLandscapeRight;
}
CainaSouza
  • 1,417
  • 2
  • 16
  • 31
  • I have done the same implementation but it's not working. I have created a sample can you please check it out ? https://github.com/tariq235/ForcePortrait – Tariq Feb 01 '13 at 03:20
  • I took a look in your code and there are some changes that should be done! I edited my answer... Check it out and tell then the result... – CainaSouza Feb 01 '13 at 12:11
  • 1
    Hey first thanks for spending time on my source code. As I need second controller in Force Portrait mode not in Landscape mode so I changed your code of MaskLandscape to MaskPortrait. And also I updated github code as per your instructions but still its not working. My problem is if First Controller is in Landscape mode and then you click button for navigation then Second Controller should not be visible in Landscape. It should do Force portrait rotation. – Tariq Feb 01 '13 at 12:35
  • I ran your code and it's really not working... I can't understand why doesn't work. I'll check on it again later. Did you got it fixed? – CainaSouza Feb 01 '13 at 16:44
  • I am trying hard since couple of days but its not working. I have tried all possible ways but not able to figure out exact problem. Please let me know if you find out something. Thanks – Tariq Feb 01 '13 at 16:56
  • Yup I solved it... Check my answer... I am not sure this is 100% correct or not but thats working for me – Tariq Feb 01 '13 at 18:33
  • 3
    In fact this is a workaround that shouldn't be done! But it really works!haha – CainaSouza Feb 01 '13 at 20:30