Force portrait orientation while pushing from landscape View Controller
Asked Answered
Z

2

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

Zinfandel answered 31/1, 2013 at 19:4 Comment(0)
Z
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];
Zinfandel answered 1/2, 2013 at 18:33 Comment(10)
+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.Crocker
If you're going to be calling the view more than once, I suggest that add those lines to the viewWillAppear.Vidda
But this API is deprecated since iOS6... :/Wendel
it does not work on Ipad when i implement this solution a black screen comes in.Exit
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 knowCampeche
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?Subversive
@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.Ketubim
Sorry everyone. I'll investigate the issue and will post the solution.Zinfandel
@Zinfandel Yes its working fine during pusing time but not working on pop time. it crashing. please help me out on this.Dwyer
Had to change to [c dismissViewControllerAnimated:NO completion:nil]; but still works in ios 9!Deaden
L
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;
}
Luxuriant answered 31/1, 2013 at 19:14 Comment(7)
I have done the same implementation but it's not working. I have created a sample can you please check it out ? github.com/tariq235/ForcePortraitZinfandel
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...Luxuriant
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.Zinfandel
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?Luxuriant
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. ThanksZinfandel
Yup I solved it... Check my answer... I am not sure this is 100% correct or not but thats working for meZinfandel
In fact this is a workaround that shouldn't be done! But it really works!hahaLuxuriant

© 2022 - 2024 — McMap. All rights reserved.