简体   繁体   中英

Presenting a ViewController From AppDelegate

I am writing a function that will be called when my application receives a remote notification locally. First, a banner is displayed using the library BRYXBanner, then if and when the user taps on the banner, it will call this function which should present a view controller called ChatLogViewController. This function may be called from any place within the app so one of the parameters for the function is fromViewController. I am trying to figure out two issues.

  1. How to present ChatLogViewController from anywhere within the app using the function GoToChatLogVC()

Code:

func GoToClassVC(fromVC : UIViewController, toClassID: String) {
    let chatLog = ChatLogViewController()
    fromVC.present(chatLog, animated: true) {
        chatLog.classID = toClassID
    }
}
  1. How to assign this function to a property of type (()->())?

功能代码截图

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)

Thank you for your help!

To solve this ERROR Cannot assign value of type '()' to type '(() -> ())?'

replace the code this

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

to this

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

For This: How to present ChatLogViewController from anywhere within the app using the function GoToChatLogVC()

Your currentVC replace to 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;
            }
        }
    }
}

If you want to present ViewController from anywhere then you can present it on rootViewController of UIWindow like below.

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

To present a view controller from app delegate you can use the following:

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

The best approach is this:

1- add this extension at top of your AppDelegate class :

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- Now you can present your view controller easily:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM