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


当前回答

如果你正在使用一个导航控制器,只是想知道你是否在活动和最顶层的控制器,那么使用:

if navigationController?.topViewController == self {
    // Do something
}

这个答案是基于@mattdipasquale的评论。

如果您有一个更复杂的场景,请参阅上面的其他答案。

其他回答

好的观点是,如果视图已经在窗口层次结构堆栈中出现。 因此,我们可以扩展类来实现这个功能。

extension UIViewController {
  var isViewAppeared: Bool { viewIfLoaded?.isAppeared == true }
}

extension UIView {
  var isAppeared: Bool { window != nil }
}

我根据@ program的回答做了一个快速扩展。

它允许你很容易地检查UIViewController是否在屏幕上,就像这样:

if someViewController.isOnScreen {
    // Do stuff here
}

扩展:

//
//  UIViewControllerExtension.swift
//

import UIKit

extension UIViewController{
    var isOnScreen: Bool{
        return self.isViewLoaded() && view.window != nil
    }
}

对于超全屏或超上下文模式表示,“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属性。

就我的目的而言,在容器视图控制器的上下文中,我已经找到了

- (BOOL)isVisible {
    return (self.isViewLoaded && self.view.window && self.parentViewController != nil);
}

工作得很好。