如果当前打开特定的 ViewController,如何检查 AppDelegate

Posted

技术标签:

【中文标题】如果当前打开特定的 ViewController,如何检查 AppDelegate【英文标题】:How to check in AppDelegate if a particular ViewController is currently open 【发布时间】:2018-11-07 15:22:04 【问题描述】:

当某个userMessagesViewController 当前打开时,我试图阻止在应用主屏幕上显示推送通知。 如果这个特定的viewController 是打开的,我不希望用户收到推送通知。我发送推送通知的函数在appDelegate 中。我该如何检查。到目前为止,这是我的实现。

  let messagesVC = UserMessageViewController()

    if messagesVC.view.window != nil 
        print("Messages viewcontroller is visible and open")
         else 
        print("Messages viewcontroller isnt visible and not open")
    

【问题讨论】:

this 相关吗? 如果您不想扩展 UIApplication,只需考虑一个选项,即创建一个单例属性,消息控制器在进入和离开视图时切换该属性。消息控制器还可以在应用程序委托可以侦听的视图进入和退出时发布通知。应用程序委托可以检查此属性以确定它是否应该发布。只是需要考虑的选项。 【参考方案1】:

通过启动messagesVC,您正在创建一个尚未呈现的全新UserMessageViewController。您想要的控制器的特定实例已经实例化,因此您必须使用视图控制器层次结构找到它。

AppDelegate 让您可以访问应用程序的rootViewController,这将是您故事板中的第一个控制器。通过这个控制器,您可以通过子视图控制器搜索UserMessageViewController

这是一个扩展,它将从 rootViewController 开始并向上冒泡,直到到达视图控制器层次结构堆栈的顶部。

extension UIApplication 
    func topViewController(_ base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? 
        switch (base) 
        case let controller as UINavigationController:
            return topViewController(controller.visibleViewController)
        case let controller as UITabBarController:
            return controller.selectedViewController.flatMap  topViewController($0)  ?? base
        default:
            return base?.presentedViewController.flatMap  topViewController($0)  ?? base
        
    

创建一个名为UIApplication+TopViewController.swift 的新文件并粘贴上述扩展名。然后在AppDelegate 中,您将能够使用UIApplication.shared.topViewController() 获取当前正在呈现的视图控制器:

if let messagesVC = UIApplication.shared.topViewController() as? UserMessageViewController 
    print("Messages viewcontroller is visible and open")
 else 
    print("Messages viewcontroller isnt visible and not open")

通过将顶视图控制器转换为UserMessageViewController,我们可以确定是否应该显示通知。

【讨论】:

【参考方案2】:

这应该适合你:

if messagesVC.viewIfLoaded?.window != nil 
    // viewController is visible, handle notification silently.

您的appDelegate 将引用 VC。它可能应该是委托的属性

【讨论】:

以上是关于如果当前打开特定的 ViewController,如何检查 AppDelegate的主要内容,如果未能解决你的问题,请参考以下文章

如何移动到 pageViewController 中的特定页面?

应用程序打开到导航控制器内的特定 ViewController

在tableView中打开特定的viewController

收到通知并启用 Touch ID 时如何打开特定的 ViewController

截取当前未打开的 ViewController 的屏幕截图

为啥我的 UIViewController 失去了对打开模式 ViewController 的引用?