UINavigationController方向更改中的ViewController

所以我有以下层次结构:

UINavigationController – > RootViewController( UIViewController ) – > UITableViewController – > DetailViewController( UIViewController

我想lockingRootViewController上的方向为只有肖像,但保留其余视图控制器的所有方向。

如果我把这个子类UINavigationController

 - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } -(NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; } 

所有的视图控制器然后locking到肖像。

我的问题是,有没有办法只lockingRootViewController到肖像,但保留其他视图控制器的所有选项?

检查在这里的链接修复在iOS 6自动旋转,并设置定位支持每个视图的基础: http : //www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/

这是你可以做的:

  1. 在.m文件中创build一个自定义的导航控制器,它是UINavigationController一个子类:

      - (BOOL)shouldAutorotate { return self.topViewController.shouldAutorotate; } - (NSUInteger)supportedInterfaceOrientations { return self.topViewController.supportedInterfaceOrientations; } 
  2. 在你的AppDelegate.h

      @interface AppDelegate : UIResponder <UIApplicationDelegate> { UINavigationController *navigationController; ViewController *viewController; } @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) ViewController *viewController; 

    AppDelegate.m

      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // set initial view self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; viewController = [[ViewController alloc] initWithNibName:@"RootViewController" bundle:nil]; navigationController = [[CustomNavigationController alloc] initWithRootViewController:viewController]; // iOS 6 autorotation fix [navigationController setNavigationBarHidden:YES animated:NO]; self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [self.window setRootViewController:navigationController]; // iOS 6 autorotation fix //[self.window addSubview:navigationController.view]; [self.window makeKeyAndVisible]; return YES; } - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window // iOS 6 autorotation fix { return UIInterfaceOrientationMaskAll; } 
  3. 在你的rootViewController中,无论事件推第二个视图控制器,请执行以下操作:

      - (IBAction)pushSecondViewController:(id)sender { // push second view controller SecondViewController *secondViewController = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; [self.navigationController pushViewController:secondViewController animated:YES]; } 
  4. 在你的每个视图控制器中,添加

      - (BOOL)shouldAutorotate{} - (NSUInteger)supportedInterfaceOrientations{} 

    对于iOS 6,您可以设置每个视图控制器,无论您想要单独定向支持。

    对于iOS 5及以下版本,您可以设置

      - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{} 

所有的积分都是在链接中编写示例应用程序的John DiSalvo。

希望这可以帮助。

在单身人士

 -(void)setOrientationSupport:(BOOL)flag{ flag_orientationSupport_ = flag; } -(BOOL)getOrientationSupport{ return flag_orientationSupport_; } 

在appdelegate

 - (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { if ([singleton getOrientationSupport]) return UIInterfaceOrientationMaskAll; else return UIInterfaceOrientationMaskPortrait; } 

在viewwillappear中添加下面的代码

对于您希望支持方向的视图控制器

 [singleton setOrientationSupport:YES]; 

到那些你想要禁用方向的控制器

 [singleton setOrientationSupport:NO]; 

把它放在您的导航控制器中:

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

现在,将其添加到您的根视图控制器:

 - (BOOL)shouldAutorotate { return NO; } 

这应该做到这一点!

为了将定义允许的方向的责任委托给UINavigationController的子视图,可以使用导航控制器的visibleViewController属性使导航控制器“询问”它的支持方向的子视图。 下面的代码应该工作(Swift):

  1. 分类导航控制器:

     override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { if let visibleView = self.visibleViewController { return visibleView.supportedInterfaceOrientations() } else { return UIInterfaceOrientationMask.All } } 
  2. 导航控制器的子视图(根视图):

     // Restrict to portrait override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { return UIInterfaceOrientationMask.Portrait } 

我一直在寻找解决scheme几个小时!

所以到处实施所需的方法之后。 shouldAutorotate不需要设置为YES因为它已被设置为默认值:

 - (NSUInteger)supportedInterfaceOrientations{ return UIInterfaceOrientationMaskPortrait; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{ return UIInterfaceOrientationPortrait; } 

当显示UIViewController需要与其他视图不同的方向的时候,我在里面创build了一个UIStoryboardSegue

 #import "Showing.h" @implementation Showing - (void)perform{ NSLog(@"Showing"); UIViewController *sourceVC = self.sourceViewController; UIViewController *presentingVC = self.destinationViewController; [sourceVC.navigationController presentViewController:presentingVC animated:YES completion:nil]; } @end 

UIStoryboard里面我用这个segue( 显示 )连接了视图:

在这里输入图像说明

这很重要,你正在使用

 presentViewController:animated:completion: 

并不是

 pushViewController:animated: 

否则方向将不会再被确定。


我一直在尝试像

 [UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait]; 

或者UIViewController里面的方向应该改变的地方,我也UIStoryboardSeguespresentingViewController dismissViewControllerdismissViewController之前在我的自定义UIStoryboardSegues调用它:

 [UIViewController attemptRotationToDeviceOrientation]; 

要么

 NSNumber *numPortrait = [NSNumber numberWithInt:UIInterfaceOrientationPortrait]; [[UIDevice currentDevice] setValue:numPortrait forKey:@"orientation"]; 

但没有一个人工作。 当然,最后一个例子不应该是一个选项,因为如果苹果将改变他们的API的任何东西,这可能会导致您的应用程序内的问题。

我也尝试使用AppDelegate方法,并且在查找实际的visibleViewController的正确UIInterfaceOrientation后,总是确定此方法内的方向,但是当从一个方向切换到另一个方向时,有时会发生崩溃。 所以我仍然想知道为什么它变得如此复杂,似乎也没有任何文件解释正确。 即使下面这部分没有帮助我。