欺骗preferredInterfaceOrientationForPresentation在视图控制器更改时触发

7

我正在使用来自这里MSNavigationPaneViewController,并且已经实现了旋转的功能。 我在我的根UINavigationController中重写了旋转方法。

-(BOOL)shouldAutorotate
{
    return YES;
}
-(NSUInteger)supportedInterfaceOrientations
{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    if (appDelegate.topViewController != nil) {
        return [appDelegate.topViewController supportedInterfaceOrientations];
    } else {
        return UIInterfaceOrientationMaskPortrait;
    }
}
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    if (appDelegate.topViewController != nil) {
        return [appDelegate.topViewController preferredInterfaceOrientationForPresentation];
    } else {
        return UIInterfaceOrientationPortrait;
    }
}

我使用presentViewController: animated:completion:方法推出了MSNavigationPaneViewController,并且使得某些视图可以具有不同的方向。问题在于:每个具有不同方向的视图需要用户倾斜手机才能改变方向,此时它会锁定正确的方向。 我已经阅读了很多资料以使其工作,并且似乎需要在加载每个视图之前触发preferredInterfaceOrientationForPresentation,但它没有触发。 我认为它没有触发是因为MSNavigationPaneViewController没有使用presentViewController来更改视图控制器。 以下是MSNavigationPaneViewController用于更改视图的代码:

- (void)setPaneViewController:(UIViewController *)paneViewController
{
    if (_paneViewController == nil) {

        paneViewController.view.frame = _paneView.bounds;
        _paneViewController = paneViewController;
        [self addChildViewController:_paneViewController];
        [_paneView addSubview:_paneViewController.view];
        [_paneViewController didMoveToParentViewController:self];

    } else if (_paneViewController != paneViewController) {

        paneViewController.view.frame = _paneView.bounds;
        [_paneViewController willMoveToParentViewController:nil];
        [self addChildViewController:paneViewController];

        void(^transitionCompletion)(BOOL finished) = ^(BOOL finished) {
            [_paneViewController removeFromParentViewController];
            [paneViewController didMoveToParentViewController:self];
            _paneViewController = paneViewController;
        };

        [self transitionFromViewController:_paneViewController
                          toViewController:paneViewController
                                  duration:0
                                   options:UIViewAnimationOptionTransitionNone
                                animations:nil
                                completion:transitionCompletion];
    }
}

看起来只是在切换viewController,因此没有调用preferredInterfaceOrientationForPresentation。有没有办法强制调用preferredInterfaceOrientationForPresentation,或者通过隐藏视图来欺骗它被调用?

谢谢

编辑 ----

我完全理解iOS6中新的旋转系统是如何工作的,以及它由根管理。但是,只有在使用正确的方法之一“presented”下一个视图时,才会调用preferredInterfaceOrientationForPresentation。如果仅切换窗口,则不会调用该方法。因此,我确实需要一种方法来欺骗它被调用。

2个回答

9
你可以通过重置窗口的rootViewController来欺骗窗口重新评估其支持的界面方向。
UIApplication *app = [UIApplication sharedApplication];
UIWindow *window = [[app windows] objectAtIndex:0];
UIViewController *root = window.rootViewController;
window.rootViewController = nil;
window.rootViewController = root;

您需要确保该代码执行时,根视图控制器的-supportedInterfaceOrientations方法返回正确的掩码(对应于您想要强制设置的方向)。

请注意,这种hack可能会在屏幕上快速闪烁并使任何正在进行的动画出现故障。


谢谢。这确实使旋转改变了 :-) 这种解决方案唯一的问题是,任何当前显示的模态视图都会被隐藏。可能在根视图后面。不过我已经想出了一个hack方法,在切换rootViewController后重新呈现当前模态视图。谢谢。 - Darren
这在iOS 7中似乎对我无效,至少在父/子视图控制器设置中是如此。 - taber
适用于iOS 7。非常流畅。 - Sergey Grischyov

6

嗨,谢谢。我已经完成了这个操作,使shouldRotate工作正常。问题是,即使在导航控制器中,preferredInterfaceOrientation也不会被调用,除非你“呈现”下一个视图,而不仅仅是切换它。 - Darren
大家好, 我是iOS开发的新手,有人可以指导我如何添加这个子类吗? - janitheshan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接