13

所以我有以下层次结构:

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,但将所有选项留给其他视图控制器?

4

5 回答 5

27

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

这是您可以执行的操作:

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

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

希望这可以帮助。

于 2013-01-18T16:13:05.887 回答
2

在单身

-(void)setOrientationSupport:(BOOL)flag{

    flag_orientationSupport_ = flag;
}

-(BOOL)getOrientationSupport{

    return flag_orientationSupport_;
}

在应用程序中

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{

    if ([singleton getOrientationSupport])
        return UIInterfaceOrientationMaskAll;
    else
        return UIInterfaceOrientationMaskPortrait;
}

在viewwillappear中添加如下代码

对于您想要支持方向的视图控制器

[singleton setOrientationSupport:YES];

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

[singleton setOrientationSupport:NO];
于 2014-08-19T02:33:14.300 回答
0

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

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

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

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

- (BOOL)shouldAutorotate
{
    return NO;
}

应该这样做!

于 2013-01-18T16:24:33.970 回答
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
    }
    
于 2016-02-10T13:59:29.640 回答
-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 连接起来(显示):

在此处输入图像描述

这很重要,您正在使用

presentViewController:animated:completion:

并不是

pushViewController:animated:

否则将无法再次确定方向。


我一直在尝试像

[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];

或者这个在方向应该改变的地方,我也试着在我的自定义之前UIViewController调用它:UIStoryboardSeguespresentingViewControllerdismissViewController

[UIViewController attemptRotationToDeviceOrientation];

或者

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

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

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

于 2015-03-31T11:36:05.607 回答