我有一个标签栏应用程序,有许多视图。有没有办法知道一个特定的UIViewController当前在UIViewController中是可见的?(寻找物业)


当前回答

我用于模态呈现视图控制器的方法是检查所呈现控制器的类。如果呈现的视图控制器是ViewController2,那么我将执行一些代码。

UIViewController *vc = [self presentedViewController];

if ([vc isKindOfClass:[ViewController2 class]]) {
    NSLog(@"this is VC2");
}

其他回答

你想要使用UITabBarController的selectedViewController属性。所有附加到标签栏控制器的视图控制器都有一个tabBarController属性集,所以你可以在任何视图控制器的代码中:

if([[[self tabBarController] selectedViewController] isEqual:self]){
     //we're in the active controller
}else{
     //we are not
}

对于超全屏或超上下文模式表示,“is visible”可能意味着它在视图控制器堆栈的顶部,或者只是可见,但被另一个视图控制器覆盖。

要检查视图控制器“is the top view controller”和“is visible”是否有很大不同,你应该检查视图控制器的导航控制器的视图控制器堆栈。

我写了一段代码来解决这个问题:

extension UIViewController {
    public var isVisible: Bool {
        if isViewLoaded {
            return view.window != nil
        }
        return false
    }

    public var isTopViewController: Bool {
        if self.navigationController != nil {
            return self.navigationController?.visibleViewController === self
        } else if self.tabBarController != nil {
            return self.tabBarController?.selectedViewController == self && self.presentedViewController == nil
        } else {
            return self.presentedViewController == nil && self.isVisible
        }
    }
}

如果当前视图是可见的,视图的window属性是非空的,所以检查视图控制器中的主视图:

调用view方法会导致视图被加载(如果它没有被加载),这是不必要的,也可能是不希望看到的。最好先检查一下它是否已经加载了。我添加了对isViewLoaded的调用来避免这个问题。

if (viewController.isViewLoaded && viewController.view.window) {
    // viewController is visible
}

自从iOS9以来,这变得更容易了:

if viewController.viewIfLoaded?.window != nil {
    // viewController is visible
}

或者如果你有一个UINavigationController管理视图控制器,你可以检查它的visibleViewController属性。

如果你正在使用一个UINavigationController,也想处理模式视图,以下是我使用的:

#import <objc/runtime.h>

UIViewController* topMostController = self.navigationController.visibleViewController;
if([[NSString stringWithFormat:@"%s", class_getName([topMostController class])] isEqualToString:@"NAME_OF_CONTROLLER_YOURE_CHECKING_IN"]) {
    //is topmost visible view controller
}

对于那些正在寻找Swift 2.2版本的答案的人:

if self.isViewLoaded() && (self.view.window != nil) {
     // viewController is visible
}

Swift 3:

if self.isViewLoaded && (self.view.window != nil) {
         // viewController is visible
}