How to get visible viewController from app delegate when using storyboard?

后端 未结 14 1669
小蘑菇
小蘑菇 2020-12-05 00:14

I have some viewControllers, and I don\'t use NavigationController. How can I get visible view controller in app delegate methods (e.g. appli

相关标签:
14条回答
  • 2020-12-05 00:58

    If your app's root view controller is a UINavigationController than you can use this:

    UIViewController *currentControllerName = ((UINavigationController*)appDelegate.window.rootViewController).visibleViewController;
    

    and if you are using UITabBarController than you can use this:

    UIViewController *currentControllerName = ((UITabBarController*)appDelegate.window.rootViewController).selectedViewController;
    
    0 讨论(0)
  • 2020-12-05 00:59

    Here is an answer in Swift 4 that is very similar to the accepted answer but has a few improvements:

    1. Iterative instead of recursive.
    2. Goes all the way does the navigation stack.
    3. More "swifty" syntax.
    4. Static variable that can be put anywhere (not just in AppDelegate).
    5. Won't crash in odd cases, i.e. when a tab bar controller has no selected view controller.

      static var visibleViewController: UIViewController? {
          var currentVc = UIApplication.shared.keyWindow?.rootViewController
          while let presentedVc = currentVc?.presentedViewController {
              if let navVc = (presentedVc as? UINavigationController)?.viewControllers.last {
                  currentVc = navVc
              } else if let tabVc = (presentedVc as? UITabBarController)?.selectedViewController {
                  currentVc = tabVc
              } else {
                  currentVc = presentedVc
              }
          }
          return currentVc
      }
      
    0 讨论(0)
  • 2020-12-05 01:00

    Here is a recursive, protocol-oriented approach in Swift. Can be extended to custom types but any kind of UIViewController subclass should work with the code below.

    public protocol ViewControllerContainer {
    
        var topMostViewController: UIViewController? { get }
    }
    
    extension UIViewController: ViewControllerContainer {
    
        public var topMostViewController: UIViewController? {
    
            if let presentedView = presentedViewController {
    
                return recurseViewController(presentedView)
            }
    
            return childViewControllers.last.map(recurseViewController)
        }
    }
    
    extension UITabBarController {
    
        public override var topMostViewController: UIViewController? {
    
            return selectedViewController.map(recurseViewController)
        }
    }
    
    extension UINavigationController {
    
        public override var topMostViewController: UIViewController? {
    
            return viewControllers.last.map(recurseViewController)
        }
    }
    
    extension UIWindow: ViewControllerContainer {
    
        public var topMostViewController: UIViewController? {
    
            return rootViewController.map(recurseViewController)
        }
    }
    
    func recurseViewController(viewController: UIViewController) -> UIViewController {
    
        return viewController.topMostViewController.map(recurseViewController) ?? viewController
    }
    
    0 讨论(0)
  • 2020-12-05 01:01

    In my case i have Tabbar controller and then Navigation controller for each Tab hope it helps someone

     UIViewController *loginViewController=self.window.rootViewController;
    
     UITabBarController *controller=loginViewController.tabBarController;
    
     UIViewController *CurrentController = controller.selectedViewController.childViewControllers.lastObject;
    
    0 讨论(0)
  • 2020-12-05 01:02

    This should do it for you:

    - (void)applicationWillResignActive:(UIApplication *)application
    {
        UIViewController *vc = [self visibleViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
    }
    
    - (UIViewController *)visibleViewController:(UIViewController *)rootViewController
    {
        if (rootViewController.presentedViewController == nil)
        {
            return rootViewController;
        }
        if ([rootViewController.presentedViewController isKindOfClass:[UINavigationController class]])
        {
            UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
            UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
    
            return [self visibleViewController:lastViewController];
        }
        if ([rootViewController.presentedViewController isKindOfClass:[UITabBarController class]])
        {
            UITabBarController *tabBarController = (UITabBarController *)rootViewController.presentedViewController;
            UIViewController *selectedViewController = tabBarController.selectedViewController;
    
            return [self visibleViewController:selectedViewController];
        }
    
        UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
    
        return [self visibleViewController:presentedViewController];
    }
    
    0 讨论(0)
  • 2020-12-05 01:03

    @aviatorken89's answer worked well for me. I had to translate it to Swift - for anybody starting out with Swift:

    Updated for Swift 3:

    func getVisibleViewController(_ rootViewController: UIViewController?) -> UIViewController? {
    
        var rootVC = rootViewController
        if rootVC == nil {
            rootVC = UIApplication.shared.keyWindow?.rootViewController
        }
    
        if rootVC?.presentedViewController == nil {
            return rootVC
        }
    
        if let presented = rootVC?.presentedViewController {
            if presented.isKind(of: UINavigationController.self) {
                let navigationController = presented as! UINavigationController
                return navigationController.viewControllers.last!
            }
    
            if presented.isKind(of: UITabBarController.self) {
                let tabBarController = presented as! UITabBarController
                return tabBarController.selectedViewController!
            }
    
            return getVisibleViewController(presented)
        }
        return nil
    }
    

    Old answer:

    func applicationWillResignActive(application: UIApplication) {
        let currentViewController = getVisibleViewController(nil)
    }
    
    func getVisibleViewController(var rootViewController: UIViewController?) -> UIViewController? {
    
        if rootViewController == nil {
            rootViewController = UIApplication.sharedApplication().keyWindow?.rootViewController
        }
    
        if rootViewController?.presentedViewController == nil {
            return rootViewController
        }
    
        if let presented = rootViewController?.presentedViewController {
            if presented.isKindOfClass(UINavigationController) {
                let navigationController = presented as! UINavigationController
                return navigationController.viewControllers.last!
            }
    
            if presented.isKindOfClass(UITabBarController) {
                let tabBarController = presented as! UITabBarController
                return tabBarController.selectedViewController!
            }
    
            return getVisibleViewController(presented)
        }
        return nil
    }
    
    0 讨论(0)
提交回复
热议问题