iOS 7+关闭模态视图控制器和强制纵向方向

Jac*_*cob 13 iphone objective-c rotation screen-orientation ios

我有一个UINavigationController作为我在iOS 7和iOS 8上的UIWindow的根视图控制器.从它的一个视图控制器,我提出了一个具有交叉溶解演示风格的全屏模态视图控制器.这个模态视图控制器应该能够旋转到所有方向,并且它工作正常.

问题是当设备以横向方向保持并且模态视图控制器被解除时.呈现模态的视图控制器仅支持纵向方向,并且我已确认UIInterfaceOrientationMaskPortrait返回到-application:supportedInterfaceOrientationsForWindow:.-shouldAutorotate也返回YES.然而,在解除模态之后,呈现视图控制器的方向仍然是风景.在允许模态采取设备方向的同时,如何强制它保持纵向方向?我的代码如下:

应用代表:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        UINavigationController *navigationController = (UINavigationController *)self.deckController.centerController;
        NSArray *viewControllers = [navigationController viewControllers];
        UIViewController *top = [viewControllers lastObject];

        if (top && [top presentedViewController]) {
            UIViewController *presented = [top presentedViewController];
            if ([presented respondsToSelector:@selector(isDismissing)] && ![(id)presented isDismissing]) {
                top = presented;
            }
        }

        return [top supportedInterfaceOrientations];
    }

    return (UIInterfaceOrientationMaskLandscapeLeft|UIInterfaceOrientationMaskLandscapeRight);
}
Run Code Online (Sandbox Code Playgroud)

呈现视图控制器:

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}
Run Code Online (Sandbox Code Playgroud)

模态视图控制器:

- (BOOL)shouldAutorotate
{
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return (UIInterfaceOrientationMaskLandscape|UIInterfaceOrientationMaskLandscapeLeft|UIInterfaceOrientationMaskPortrait);
}
Run Code Online (Sandbox Code Playgroud)

asa*_* am 5

如果模态控制器在解除之前处于横向方向,则呈现的ViewController可能不会返回到原点方向(纵向).问题是因为在控制器实际被解除之前调用了AppDelegate supportedInterfaceOrientationsForWindow方法,并且呈现的控制器检查仍然返回Landscape掩码.

设置一个标志以指示是否显示(模态)显示的视图控制器.

- (void)awakeFromNib // or where you instantiate your ViewController from
{
    [super awakeFromNib];
    self.presented = YES;
}

- (IBAction)exitAction:(id)sender // where you dismiss the modal
{
    self.presented = NO;
    [self dismissViewControllerAnimated:NO completion:nil];
}
Run Code Online (Sandbox Code Playgroud)

并且在模式中呈现的ViewController根据标志设置方向:当呈现模态ViewController时 - 返回Landscape.当它被解雇然后返回肖像

- (NSUInteger)supportedInterfaceOrientations
{
    if ([self isPresented]) {
        return UIInterfaceOrientationMaskLandscape;
    } else {
        return UIInterfaceOrientationMaskPortrait;
    }
}
Run Code Online (Sandbox Code Playgroud)

最后一步 - 从你的AppDelegate调用模态呈现ViewController的方向.我只是检查当前呈现的ViewController并在其上调用supportedInterfaceOrientations

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    NSUInteger orientationMask = UIInterfaceOrientationMaskPortrait;

    UIViewController *currentVC = self.window.rootViewController.presentedViewController; // gets the presented VC
    orientationMask = [currentVC supportedInterfaceOrientations];

    return orientationMask;
}
Run Code Online (Sandbox Code Playgroud)

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


Jac*_*cob 1

我最终对 UINavigationController 进行子类化并重写其旋转方法。以下解决方案适用于 iOS 7,但我相信 iOS 8 beta 5 中存在一个错误,导致呈现视图控制器的视图在横向关闭模式后缩小到屏幕高度的一半。

UINavigationController 子类:

- (BOOL)shouldAutorotate
{
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationPortrait;
}
Run Code Online (Sandbox Code Playgroud)