如何使用故事板从应用程序委托可见viewController?

我有一些viewControllers ,我不使用NavigationController 。 我怎样才能得到可见的视图控制器在应用程序委托方法(如applicationWillResignActive )?

我知道如何从NSNotification做到这一点,但我认为这是错误的方式。

这应该为你做:

 - (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]; } 

@ aviatorken89的答案对我很好。 我不得不把它翻译成Swift – 对于任何从Swift开始的人来说:

更新了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 } 

老答案:

 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 } 

我们把它作为一个UIApplication扩展来实现:

 import UIKit extension UIApplication { var visibleViewController: UIViewController? { guard let rootViewController = keyWindow?.rootViewController else { return nil } return getVisibleViewController(rootViewController) } private func getVisibleViewController(_ rootViewController: UIViewController) -> UIViewController? { if let presentedViewController = rootViewController.presentedViewController { return getVisibleViewController(presentedViewController) } if let navigationController = rootViewController as? UINavigationController { return navigationController.visibleViewController } if let tabBarController = rootViewController as? UITabBarController { return tabBarController.selectedViewController } return rootViewController } } 

这里是Swift中的一个recursion的,面向协议的方法。 可以扩展到自定义types,但任何types的UIViewController子类都应该使用下面的代码。

 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 } 

如果你的应用程序的根视图控制器是一个UINavigationController比你可以使用这个:

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

如果你使用的是UITabBarController,那么你可以使用这个:

 UIViewController *currentControllerName = ((UITabBarController*)appDelegate.window.rootViewController).selectedViewController; 

这里最重要的build议在许多情况下都能正常工作,以获得“最佳猜测”解决scheme,但只需稍作调整,我们就可以获得一个更完整的解决scheme,而不依赖于您的应用程序的视图层次结构实现。

1)Cocoa Touch的视图层次结构允许多个孩子同时出现和可见,所以我们需要替代地询问当前可见的视图控制器(复数)并相应地处理结果

2) UINavigationControllerUITabBarController通常在iOS应用程序中使用,但它们不是唯一的容器视图控制器。 UIKit还提供了UIPageViewControllerUISplitViewController ,并允许您编写自己的自定义容器视图控制器。

3)我们可能想忽略popup窗口模式和特定types的视图控制器,如UIAlertController或定制的embedded式子视图控制器。

 private func visibleViewControllers() -> [UIViewController] { guard let root = window?.rootViewController else { return [] } return visibleLeaves(from: root, excluding: [UIAlertController.self]) } private func visibleLeaves(from parent: UIViewController, excluding excludedTypes: [UIViewController.Type] = []) -> [UIViewController] { let isExcluded: (UIViewController) -> Bool = { vc in excludedTypes.contains(where: { vc.isKind(of: $0) }) || vc.modalPresentationStyle == .popover } if let presented = parent.presentedViewController, !isExcluded(presented) { return self.visibleLeaves(from: presented, excluding: excludedTypes) } let visibleChildren = parent.childViewControllers.filter { $0.isViewLoaded && $0.view.window != nil } let visibleLeaves = visibleChildren.flatMap { return self.visibleLeaves(from: $0, excluding: excludedTypes) } if visibleLeaves.count > 0 { return visibleLeaves } else if !isExcluded(parent) { return [parent] } else { return [] } } 

下面是@ ProgrammierTier的答案Swift 2.3实现作为UIViewController的扩展

 extension UIViewController { var visibleViewController: UIViewController? { if presentedViewController == nil { return self } if let presented = 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 presented.visibleViewController } return nil } } 

applicationWillResignActive获取它

 func applicationWillResignActive(application: UIApplication) { let visibleVC = application.keyWindow?.rootViewController?.visibleViewController } 

在我的情况下,我有Tabbar控制器,然后导航控制器为每个选项卡希望它可以帮助某人

  UIViewController *loginViewController=self.window.rootViewController; UITabBarController *controller=loginViewController.tabBarController; UIViewController *CurrentController = controller.selectedViewController.childViewControllers.lastObject; 

如果您使用的是IQKeyboardManager,那么在那里有一个扩展名

  • (的UIViewController *)currentViewController;

所以你可以做

  application.keyWindow?.currentViewController? // <- there you go 

所以把它添加到你的pod文件中

 pod 'IQKeyboardManager' then pod update and you are away! 

希望这可以帮助

从部队231修改

 + (UIViewController *)visibleViewController:(UIViewController *)rootViewController { if ([rootViewController isKindOfClass:[UINavigationController class]]) { UINavigationController *navigationController = (UINavigationController *)rootViewController; UIViewController *lastViewController = [[navigationController viewControllers] lastObject]; return [self visibleViewController:lastViewController]; } if ([rootViewController isKindOfClass:[UITabBarController class]]) { UITabBarController *tabBarController = (UITabBarController *)rootViewController; UIViewController *selectedViewController = tabBarController.selectedViewController; return [self visibleViewController:selectedViewController]; } if (rootViewController.presentedViewController != nil) { UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController; return [self visibleViewController:presentedViewController]; } return rootViewController; }