搜索
您的当前位置:首页正文

iOS开发获取当前控制器

来源:二三娱乐

iOS项目开发中,经常会遇到需要知道应用正在显示哪个控制器的情况。比如,当收到一条推送通知时,要根据不同界面处理不同的业务逻辑,就需要知道收到通知时应用正处于哪个界面,即获取到应用正在显示的控制器。下面介绍一种方法,分别用swift和OC实现。

swift版:

func getCurrentVC() -> UIViewController? {
    for window in UIApplication.shared.windows.reversed() {
        var tempView: UIView? = window.subviews.last
        for subview in window.subviews.reversed() {
            if subview.classForCoder == NSClassFromString("UILayoutContainerView") {
                tempView = subview
                break
            }
        }
        
        var nextResponder = tempView?.next
        
        var next: Bool {
            return !(nextResponder is UIViewController) || nextResponder is UINavigationController || nextResponder is UITabBarController || nextResponder?.classForCoder == NSClassFromString("UIInputWindowController")
        }
        
        while next{
            tempView = tempView?.subviews.first
            if tempView == nil {
                return nil
            }
            nextResponder = tempView!.next
        }
        if let currentVC = nextResponder as? UIViewController {
            return currentVC
        }
    }
    return nil
}


OC版:

-  (UIViewController *)getCurrentVC {
     for (UIWindow *window in [UIApplication sharedApplication].windows.reverseObjectEnumerator) {
        
        UIView *tempView = window.subviews.lastObject;
        
        for (UIView *subview in window.subviews.reverseObjectEnumerator) {
            if ([subview isKindOfClass:NSClassFromString(@"UILayoutContainerView")]) {
                tempView = subview;
                break;
            }
        }
        
        BOOL(^canNext)(UIResponder *) = ^(UIResponder *responder){
            if (![responder isKindOfClass:[UIViewController class]]) {
                return YES;
            } else if ([responder isKindOfClass:[UINavigationController class]]) {
                return YES;
            } else if ([responder isKindOfClass:[UITabBarController class]]) {
                return YES;
            } else if ([responder isKindOfClass:NSClassFromString(@"UIInputWindowController")]) {
                return YES;
            }
            return NO;
        };
        
        UIResponder *nextResponder = tempView.nextResponder;
        
        while (canNext(nextResponder)) {
            tempView = tempView.subviews.firstObject;
            if (!tempView) {
                return nil;
            }
            nextResponder = tempView.nextResponder;
        }
        
        UIViewController *currentVC = (UIViewController *)nextResponder;
        if (currentVC) {
            return currentVC;
        }
    }
    return nil;

}

使用该方法的需要注意的地方是,需要等到控制器viewDidAppear之后才能获取到正确的控制器

Top