Why can't I force landscape orientation when use UINavigationController?
Asked Answered
I

2

2

I find many question to force UIViewController to landscape as default: How to force a UIViewController to Portrait orientation in iOS 6 And try this:

- (BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations

{
    return UIInterfaceOrientationMaskLandscape;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeLeft;
}

But when I use UIViewController inside UINavigationController, I can't force to landscape.Please help!

*Work NOT ok

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];

    UINavigationController *navControl = [[UINavigationController alloc] initWithRootViewController:self.viewController];
    [navControl setNavigationBarHidden:YES];
    self.window.rootViewController = navControl;

    [self.window makeKeyAndVisible];
    return YES;
}

*Work OK:

self.window.rootViewController = self.viewController;
Ibrahim answered 2/2, 2013 at 3:26 Comment(0)
L
4

Best way to do this is the create extend UINavigationController and write your orientation function inside the extended class.

Class Declaration:

@interface MyNavigationControllerViewController : UINavigationController

@property(nonatomic, assign) UIInterfaceOrientation orientation;
@property(nonatomic, assign) NSUInteger supportedInterfaceOrientatoin;
@end

Implementation of MyNavigationController

@implementation MyNavigationController

@synthesize supportedInterfaceOrientatoin = _supportedInterfaceOrientatoin;

@synthesize orientation = _orientation;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        _supportedInterfaceOrientatoin = UIInterfaceOrientationMaskLandscape;
        _orientation = UIInterfaceOrientationLandscapeLeft;
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (BOOL)shouldAutorotate
{
    return YES;
}

-(NSUInteger)supportedInterfaceOrientations

{
    return _supportedInterfaceOrientatoin;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return self.orientation;
}

@end

and use your extended like MyNavigationController as navigation controller to your rootviewcontroller.

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) ViewController *viewController;
@property (strong, nonatomic) MyNavigationControllerViewController *myNavController;

- (void) reloadAppDelegateRootViewControllerLandscape;
- (void) reloadAppDelegateRootViewController;
@end

So your application delegate didfinishlounchingwithoptions code will be as follow.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];

    self.myNavController = [[MyNavigationController alloc] initWithRootViewController:self.viewController];
    [self.myNavController setNavigationBarHidden:YES];
    self.window.rootViewController = self.myNavController;

    [self.window makeKeyAndVisible];
    return YES;
}

Only way you can provide different orientation for two different view with same navigation controller isto reload the navigation controller itself. So if you add two methods

- (void) reloadAppDelegateRootViewController{
    [[[UIApplication sharedApplication].delegate window] setRootViewController:nil];
    [(MyNavigationControllerViewController *)self.myNavController setOrientation:UIInterfaceOrientationPortrait];
    [(MyNavigationControllerViewController *)self.myNavController setSupportedInterfaceOrientatoin:UIInterfaceOrientationMaskAll];
    [[[UIApplication sharedApplication].delegate window] setRootViewController:self.myNavController];
}

- (void) reloadAppDelegateRootViewControllerLandscape{
    [[[UIApplication sharedApplication].delegate window] setRootViewController:nil];
    [(MyNavigationControllerViewController *)self.myNavController setOrientation:UIInterfaceOrientationLandscapeLeft];
    [(MyNavigationControllerViewController *)self.myNavController setSupportedInterfaceOrientatoin:UIInterfaceOrientationMaskLandscape];
    [[[UIApplication sharedApplication].delegate window] setRootViewController:self.myNavController];
}

and call these function after pushing and pop views.

Note:- I don't know whether it is a good way or bad way.

Lindbergh answered 2/2, 2013 at 4:16 Comment(6)
I just have 1UINavigationController for all UIViewController.Where is the suitable place to create custom navigationController programmatically.Please guide some code!Ibrahim
please check is it ok for your u.Lindbergh
Thanks!But My UINavigation just support landscape only.When push to next UIViewController,it don't support portrait: github.com/lequysang/TestOrientIbrahim
My target: root(landscape) -> next UIViewController(portrait + landscape)Ibrahim
please check the code i have uploaded on my github github.com/sunilpandey/DifferentOrientationLindbergh
I haven't checked this but won't it cause the new view to be pushed on the stack with the old orientation and then "jump" to the new orientation after the push is complete? Don't you want it such that the target VC will be in it's proper orientation for the push while the previous VC remains in it's orientation?Accumulation
E
-3

You need to go to your plist file and set the orientations. You can also do this on your project file. The plist orientations settings will override all though.

In your plist you can set both orientation options to landscape button left and landscape button right.

Elanaeland answered 2/2, 2013 at 3:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.