首页 > 解决方案 > 如何检查 UIViewController 是否已经显示?

问题描述

我正在开发一个应用程序,该应用程序显示带有一些信息的今日扩展。当我点击今天的扩展时,它会打开应用程序并从根导航到子视图以显示信息。通常,用户会单击后退箭头返回主视图,但无法判断这是否真的完成了。用户可以返回到今天的扩展并再次点击。完成后,子视图将再次打开并显示新信息。如果多次这样做,我最终会得到一堆子视图的实例,我必须单击每个实例上的后退按钮才能返回主视图。

我的问题:是否可以检查子视图是否已经可见?我希望能够只向它发送更新的信息,而不必显示一个全新的视图。

我目前正在通过将实例保留在UIViewController我的根目录顶部来处理这个问题。如果它不为零,那么我只是将信息传递给它并重绘。如果它是 nil,那么我调用performSegue并创建一个新的。

我只是认为必须有更好的方法来处理这个问题。

编辑:感谢下面的评论者,我想出了这段代码,似乎可以满足我的需要。

        if let quoteView = self.navigationController?.topViewController as? ShowQuoteVC {
            quoteView.updateQuoteInformation(usingQuote: QuoteService.instance.getQuote(byQuoteNumber: quote))
        }
        else {
            performSegue(withIdentifier: "showQuote", sender: quote)
        }

这与答案是建议的帖子不同:

if (self.navigationController.topViewController == self) {
    //the view is currently displayed
}

在这种情况下,它不起作用,因为当我从 Today Extension 进入应用程序时,它进入了根视图控制器。我需要检查是否正在显示子视图,而 self.navigationController.topViewcontroller == self 将永远无法工作,因为我没有检查顶视图控制器是否是根视图控制器。这篇文章中的建议更适用于我想要完成的事情。

标签: swiftuiviewcontroller

解决方案


你可以使用这个扩展来检查当前通过 UIApplication UIViewController 显示的内容:

extension UIApplication {
    class func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
        if let nav = base as? UINavigationController {
            return topViewController(base: nav.visibleViewController)
        }
        if let tab = base as? UITabBarController {
            if let selected = tab.selectedViewController {
                return topViewController(base: selected)
            }
        }
        if let presented = base?.presentedViewController {
            return topViewController(base: presented)
        }
        return base
    }
}

和用法示例:

 if let topController =  UIApplication.topViewController() {
        if !topController.isKind(of: MainViewController.self) { //MainViewController- the controller u wish to equal its type
            // do action...
        }
    }

推荐阅读