UINavigationController中的ViewController方向更改

时间:2013-01-18 15:43:30

标签: iphone ios ipad uinavigationcontroller orientation

所以我有以下层次结构:

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

我想将RootViewController上的方向锁定为仅限纵向,但保留其余视图控制器的所有方向。

如果我把它放到子类UINavigationController

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

-(NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

然后将所有视图控制器锁定为纵向。

我的问题是,有没有办法只将RootViewController锁定为Portrait,但保留其他视图控制器的所有选项?

5 个答案:

答案 0 :(得分:27)

检查此处的链接,以便在iOS 6中修复自动旋转,并根据每个视图设置方向支持:http://www.disalvotech.com/blog/app-development/iphone/ios-6-rotation-solution/

以下是您可以做的事情:

  1. 在.m文件中创建一个自定义导航控制器,它是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中的
  4. ,无论事件是什么推动第二个视图控制器,都要这样做:

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

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

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

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

       - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{}
    
  7. 所有学分都归John DiSalvo所有,他在链接中编写了示例应用程序。

    希望这有帮助。

答案 1 :(得分:1)

in singleton

-(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

中添加以下代码

对于想要支持方向的viewcontroller

[singleton setOrientationSupport:YES];

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

[singleton setOrientationSupport:NO];

答案 2 :(得分:0)

将它放在导航控制器中:

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

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

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

- (BOOL)shouldAutorotate
{
    return NO;
}

应该这样做!

答案 3 :(得分:0)

要将定义允许的方向的责任委托给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
    }
    

答案 4 :(得分:-1)

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

所以在各地实施所需的方法之后。 shouldAutorotate不需要设置为YES,因为它已设置为默认值:

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{
     return UIInterfaceOrientationPortrait;
}

当需要显示需要与其他视图不同的方向的UIViewController时,我在内部创建了一个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连接了视图(显示):

enter image description here

重要的是,你正在使用

presentViewController:animated:completion:

AND NOT

pushViewController:animated:

否则将不再确定方向。

<小时/> 我一直在尝试像

这样的事情
[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];

这个方向应该更改的UIViewController内的这个,我也尝试在UIStoryboardSegues和{{{{}}之前在我的自定义presentingViewController内调用它1}}:

dismissViewController

[UIViewController attemptRotationToDeviceOrientation];

但他们中没有人工作过。当然最后一个例子不应该是一个选项,因为如果苹果会改变他们api的任何内容,这可能会导致你的应用程序内部出现问题。

我还尝试使用NSNumber *numPortrait = [NSNumber numberWithInt:UIInterfaceOrientationPortrait]; [[UIDevice currentDevice] setValue:numPortrait forKey:@"orientation"]; 方法,并在查找实际AppDelegate的正确UIInterfaceOrientation后始终确定此方法内的方向,但有时在切换时有时会崩溃从一个到另一个方向。所以我仍然想知道为什么它变得如此复杂,似乎也没有任何文档可以正确解释。 甚至关注this part didn't help我。