8

我设置了以下视图控制器:

viewController1 可以自由旋转到任何方向,除了纵向倒置。

viewController2 被推到 viewController1 的顶部,我希望它与 viewController1 的方向相同,并且我希望它不能旋转。

viewController3 被推到 viewController2 之上。我希望 viewController3 处于纵向模式。

我在尝试在 iOS6 中完成此操作时遇到了很多问题(在 iOS5 中尚未尝试过)。首先,我已经创建了自己的导航控制器并将以下内容放入其中:

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [self.topViewController preferredInterfaceOrientationForPresentation];
}

- (NSUInteger)supportedInterfaceOrientations
{
    return [self.topViewController supportedInterfaceOrientations];
}

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

我已经尝试了很多这些东西的不同组合以了解是否有用。如果 vc2 处于横向状态,我主要在苦苦挣扎的地方是强制 vc3 显示为纵向。任何帮助,将不胜感激。

4

3 回答 3

12

您在这里尝试做的是与框架作斗争。您所描述的根本不是导航控制器架构在 iOS 6 中的工作方式。如果您想显示视图控制器的视图并强制旋转,请使用呈现的视图控制器。这是唯一preferredInterfaceOrientationForPresentation有意义的时间,并且supportedInterfaceOrientations实际上将咨询您的视图控制器,因为在呈现时,它将位于界面的根部。

于 2013-03-08T19:00:20.470 回答
5

我在另一个答案中解释说,iOS 6 不支持在将新视图控制器推到导航控制器时强制旋转。您可以构建有关补偿旋转的规则(即如果用户旋转设备会发生什么),但您不能强制界面旋转。iOS 6 很乐意让您强制旋转的唯一情况是在呈现或关闭视图控制器(presentViewController:animated:dismissViewControllerAnimated:)时。

但是,可以使用呈现的视图控制器,使其看起来像是在推动导航控制器。我制作了一部电影来表达我的意思:

http://youtu.be/O76d6FhPXlE

现在,无论如何,这并不完全完美。状态栏没有旋转动画,两个视图之间有一种黑色的“闪烁”——这是故意的,因为它是为了掩盖真正发生的事情。真正发生的是,实际上有两个不同的导航控制器和三个视图控制器,如故事板的屏幕截图所示。

在此处输入图像描述

我们拥有的是:

  • 设置为纵向的导航控制器子类及其根视图控制器

  • 第二个导航控制器子类设置为横向,以及它的根视图控制器,它是黑色的,用作中介

  • 第三个视图控制器被推送到第二个导航控制器的堆栈上

当用户要求从第一个视图控制器“前进”时,我们呈现第二个导航控制器,因此暂时看到黑色视图控制器,但随后我们立即推动第三个视图控制器。所以我们得到了强制旋转,以及一种黑色闪光和推动动画。当用户点击第三个视图控制器中的后退按钮时,我们反转该过程。

所有的过渡代码都在黑色视图控制器(ViewControllerIntermediary)中。我试图调整它以提供我能做到的最令人满意的动画:

@implementation ViewControllerIntermediary {
    BOOL _comingBack;
}

- (void) viewDidLoad {
    [super viewDidLoad];
    self.navigationController.delegate = self;
}

-(void)navigationController:(UINavigationController *)nc 
        willShowViewController:(UIViewController *)vc 
        animated:(BOOL)anim {
    if (self == vc)
        [nc setNavigationBarHidden:YES animated:_comingBack];
    else
        [nc setNavigationBarHidden:NO animated:YES];
}

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (!_comingBack) {
        [self performSegueWithIdentifier:@"pushme" sender:self];
        _comingBack = YES;
    }
    else
        [self.navigationController dismissViewControllerAnimated:YES 
            completion:nil];
}
于 2013-05-04T22:22:21.047 回答
1
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if ([self.window.rootViewController.presentedViewController isKindOfClass: [SecondViewController class]])
{
    SecondViewController *secondController = (SecondViewController *) self.window.rootViewController.presentedViewController;

    if (secondController.isPresented)
        return UIInterfaceOrientationMaskAll;
    else return UIInterfaceOrientationMaskPortrait;
}
else return UIInterfaceOrientationMaskPortrait;
}

对于斯威夫特

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow) -> Int {

    if self.window?.rootViewController?.presentedViewController? is SecondViewController {

        let secondController = self.window!.rootViewController.presentedViewController as SecondViewController

        if secondController.isPresented {
            return Int(UIInterfaceOrientationMask.All.toRaw());
        } else {
            return Int(UIInterfaceOrientationMask.Portrait.toRaw());
        }
    } else {
        return Int(UIInterfaceOrientationMask.Portrait.toRaw());
    }

}

有关更多详细信息,请查看此链接

于 2014-12-19T07:55:06.117 回答