寻找屏幕正在显示的控制器

背景

最近在撸播放器的代码,在做播放器全屏切换时为了让播放器在项目不支持横屏的情况下依然能够横屏显示,需要将播放器放在一个单独的控制器中,并且设置这个控制器支持横竖屏。
在这种情况下,需要将创建的控制器通过模态的方式展现,此时我们需要知道屏幕上正在展示的控制器。

思路

能够改变当前显示的控制器的方式无非几种:
UITabBarController 切换选中的控制器。
UINavigationController pop或者push。
UIViewController 通过模态弹出另一个控制器。

在了解了以上之后,我们还需要一个查询的入口。
App启动后显示的第一个控制器一定是根控制器。
因此我们可以通过app根控制器来一级一级向上查询。

代码

+ (UIViewController *)topViewController {
    //找到根视图
    UIViewController * rootVC = [UIApplication sharedApplication].keyWindow.rootViewController;
    return [rootVC see_topViewController];
}

- (UIViewController *)see_topViewController {
    //首先查询当前控制器是否模态出了另一个控制器,如果有则使用模态出的控制器查询
    if (self.presentedViewController) {
        return [self.presentedViewController see_topViewController];
    }
    //如果当前控制器是TabBarController则使用当前选中的控制器查询
    else if ([self isKindOfClass:[UITabBarController class]]) {
        return [((UITabBarController *)self).selectedViewController see_topViewController];
    }
    //如果当前控制器是NavigationController则使用栈顶的控制器来查询
    else if ([self isKindOfClass:[UINavigationController class]]) {
        /*关于visibleViewController和topViewController
         visibleViewcontroller 当前可见的控制器,可能是由topViewController模态出的控制器
         topViewController 栈顶控制器
        */
        return [((UINavigationController *)self).topViewController see_topViewController];
    }
    else {
            return self;
    }
}

需要注意的是,UINavigationController和UITabBarController同样可以模态别的控制器,所以在查询的时候首先要查是否有模态出的控制器,否则如果使用UINavigationController或者UITabBarController模态出了别的控制器会造成查询结果错误。

你可能感兴趣的:(寻找屏幕正在显示的控制器)