【问题标题】:Presenting a ViewController From AppDelegate从 AppDelegate 呈现 ViewController
【发布时间】:2018-02-27 17:28:57
【问题描述】:

我正在编写一个函数,当我的应用程序在本地接收到远程通知时将调用该函数。首先,使用库 BRYXBanner 显示横幅,然后当用户点击横幅时,它将调用此函数,该函数应显示名为 ChatLogViewController 的视图控制器。可以从应用程序中的任何位置调用此函数,因此该函数的参数之一是 fromViewController。我正在尝试找出两个问题。

  1. 如何使用函数 GoToChatLogVC() 从应用程序内的任何位置呈现 ChatLogViewController

代码:

func GoToClassVC(fromVC : UIViewController, toClassID: String) {
    let chatLog = ChatLogViewController()
    fromVC.present(chatLog, animated: true) {
        chatLog.classID = toClassID
    }
}
  1. 如何将此函数分配给 (()->()) 类型的属性?

guard let currentVC = self.window?.currentViewController() else {
    print("ERROR")
    return
}

let banner = Banner(title: title, subtitle: body, image: #imageLiteral(resourceName: "MessageIcon"), backgroundColor: UIColor(red:40.00/255.0, green:170.0/255.0, blue:226/255.0, alpha:1.000))

banner.show(duration: 3.0)

banner.didTapBlock = GoToClassVC(fromVC: currentVC, toClassID: self.backgroundLaunchClassID)

感谢您的帮助!

【问题讨论】:

  • 使用通知并通过通知对象向相关视图控制器发出信号。

标签: ios swift uiviewcontroller appdelegate


【解决方案1】:

解决此错误无法将类型“()”的值分配给类型“(() -> ())?”

替换代码

banner.didTapBlock = GoToClassVC(fromVC: currentVC, toClassID: self.backgroundLaunchClassID)

到这里

banner.didTapBlock = {
             self.GoToClassVC(fromVC: UIApplication.shared.keyWindow!.visibleViewController()!, toClassID:"string")
        }

为此:如何使用 GoToChatLogVC() 功能在应用内的任何位置呈现 ChatLogViewController

您的currentVC 替换为UIApplication.shared.keyWindow!.visibleViewController()!

extension UIWindow {

    func visibleViewController() -> UIViewController? {
        if let rootViewController: UIViewController = self.rootViewController {
            return UIWindow.getVisibleViewControllerFrom(vc: rootViewController)
        }
        return nil
    }

    class func getVisibleViewControllerFrom(vc:UIViewController) -> UIViewController {

        if vc.isKind(of:UINavigationController.self) {

            let navigationController = vc as! UINavigationController
            return UIWindow.getVisibleViewControllerFrom( vc: navigationController.viewControllers.first!)

        } else if vc.isKind(of:UITabBarController.self) {

            let tabBarController = vc as! UITabBarController
            return UIWindow.getVisibleViewControllerFrom(vc: tabBarController.selectedViewController!)

        }else if vc.isKind(of:UIAlertController.self) {

            let tabBarController = vc as! UIAlertController
            return UIWindow.getVisibleViewControllerFrom(vc: tabBarController)

        } else {

            if let presentedViewController = vc.presentedViewController {
                if (presentedViewController.presentedViewController != nil){
                    return UIWindow.getVisibleViewControllerFrom(vc: presentedViewController.presentedViewController!)
                }else{
                    return UIViewController()
                }

            } else {

                return vc;
            }
        }
    }
}

【讨论】:

  • 这工作(几乎),当 viewController 加载时,所有的 IBOutlets 都是 nil,这是由于 ViewController 和 Storyboard Scene 之间缺乏连接吗?如果是这样,当我使用这个功能展示它时,我将如何将 VC 链接到情节提要?
  • @KylePapili 你能告诉我你是如何从情节提要中展示你的 ViewController 的吗?以及具体的问题是什么?
  • 我已经解决了这个问题,但现在又出现了另一个问题。我正在实例化一个 NavigationController,弹出到该 NavigationController 中的 FirstViewController,然后从该 FirstViewController 调用一个 segue,将我带到所需的 ChatLogVC。但是,NavigationController 嵌入在未显示的 TabBarController 中。如何从 TabBarController 弹出到 NavigationController,然后到 FirstVC,以便能够执行所需的 segue?我附上了我的代码截图的链接。 link
【解决方案2】:

最好的办法是这样的:

1- 在 AppDelegate 类的顶部添加此扩展:

extension UIApplication{
    var topViewController: UIViewController?{
        if keyWindow?.rootViewController == nil{
            return keyWindow?.rootViewController
        }

        var pointedViewController = keyWindow?.rootViewController

        while  pointedViewController?.presentedViewController != nil {
            switch pointedViewController?.presentedViewController {
            case let navagationController as UINavigationController:
                pointedViewController = navagationController.viewControllers.last
            case let tabBarController as UITabBarController:
                pointedViewController = tabBarController.selectedViewController
            default:
                pointedViewController = pointedViewController?.presentedViewController
            }
        }
        return pointedViewController

    }
}

2- 现在您可以轻松展示您的视图控制器:

let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "net")
application.topViewController?.present(vc, animated: true, completion: nil)

【讨论】:

    【解决方案3】:

    如果您想从任何地方展示 ViewController,您可以在 rootViewControllerUIWindow 上展示它,如下所示。

    if let rootVC = UIApplication.shared.keyWindow?.rootViewController {
        let chatLog = ChatLogViewController()
        rootVC.present(chatLog, animated: true, completion: nil)
    }
    

    【讨论】:

      【解决方案4】:

      要从应用委托中呈现视图控制器,您可以使用以下内容:

      let chatLog = ChatLogViewController()
      window().rootViewController?.present(chatLog, animated: true) { _ in }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-07
        • 2015-01-13
        • 1970-01-01
        • 2020-06-29
        • 2014-11-11
        • 2015-11-14
        • 1970-01-01
        • 2013-08-26
        相关资源
        最近更新 更多