获取最顶级的UIViewController
我似乎无法获得最高UIViewController
没有访问UINavigationController
。 这是我到目前为止:
UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(vc, animated: true, completion: nil)
但是,它似乎没有做任何事情。 keyWindow
和rootViewController
似乎也是非零值,所以可选的链接不应该是一个问题。
提前致谢!
注意: 做这样的事情是一个坏主意。 它打破了MVC模式。
presentViewController
显示一个视图控制器。 它不会返回一个视图控制器。 如果你没有使用UINavigationController
,你可能正在寻找的UINavigationController
,你需要从根开始,遍历所呈现的视图。
if var topController = UIApplication.sharedApplication().keyWindow?.rootViewController { while let presentedViewController = topController.presentedViewController { topController = presentedViewController } // topController should now be your topmost view controller }
对于Swift 3+:
if var topController = UIApplication.shared.keyWindow?.rootViewController { while let presentedViewController = topController.presentedViewController { topController = presentedViewController } // topController should now be your topmost view controller }
有这个扩展
Swift 2. *
extension UIApplication { class func topViewController(controller: UIViewController? = UIApplication.sharedApplication().keyWindow?.rootViewController) -> UIViewController? { if let navigationController = controller as? UINavigationController { return topViewController(navigationController.visibleViewController) } if let tabController = controller as? UITabBarController { if let selected = tabController.selectedViewController { return topViewController(selected) } } if let presented = controller?.presentedViewController { return topViewController(presented) } return controller } }
Swift 3
extension UIApplication { class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? { if let navigationController = controller as? UINavigationController { return topViewController(controller: navigationController.visibleViewController) } if let tabController = controller as? UITabBarController { if let selected = tabController.selectedViewController { return topViewController(controller: selected) } } if let presented = controller?.presentedViewController { return topViewController(controller: presented) } return controller } }
你可以在你的控制器的任何地方使用它
if let topController = UIApplication.topViewController() { }
extension UIWindow { func visibleViewController() -> UIViewController? { if let rootViewController: UIViewController = self.rootViewController { return UIWindow.getVisibleViewControllerFrom(rootViewController) } return nil } class func getVisibleViewControllerFrom(vc:UIViewController) -> UIViewController { if vc.isKindOfClass(UINavigationController.self) { let navigationController = vc as UINavigationController return UIWindow.getVisibleViewControllerFrom( navigationController.visibleViewController) } else if vc.isKindOfClass(UITabBarController.self) { let tabBarController = vc as UITabBarController return UIWindow.getVisibleViewControllerFrom(tabBarController.selectedViewController!) } else { if let presentedViewController = vc.presentedViewController { return UIWindow.getVisibleViewControllerFrom(presentedViewController!) } else { return vc; } } }
用法:
if let topController = window.visibleViewController() { println(topController) }
基于Dianz的答案,Objective-C版本
- (UIViewController *) topViewController { UIViewController *baseVC = UIApplication.sharedApplication.keyWindow.rootViewController; if ([baseVC isKindOfClass:[UINavigationController class]]) { return ((UINavigationController *)baseVC).visibleViewController; } if ([baseVC isKindOfClass:[UITabBarController class]]) { UIViewController *selectedTVC = ((UITabBarController*)baseVC).selectedViewController; if (selectedTVC) { return selectedTVC; } } if (baseVC.presentedViewController) { return baseVC.presentedViewController; } return baseVC; }
我喜欢@Dianz的答案 ,所以这里是它的快速3版本。 这基本上是一样的,但是他错过了大括号,一些语法/variables/方法名称已经改变。 所以在这里!
extension UIApplication { class func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? { if let nav = base as? UINavigationController { return topViewController(base: nav.visibleViewController) } if let tab = base as? UITabBarController { if let selected = tab.selectedViewController { return topViewController(base: selected) } } if let presented = base?.presentedViewController { return topViewController(base: presented) } return base } }
虽然用法仍然完全相同:
if let topController = UIApplication.topViewController() { print("The view controller you're looking at is: \(topController)") }
使用这个代码find最顶级的UIViewController
func getTopViewController() -> UIViewController? { var topController: UIViewController? = UIApplication.shared.keyWindow?.rootViewController while topController?.presentedViewController != nil { topController = topController?.presentedViewController } return topController }
基于上面的Bob -c:
Swift 3.0
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.visibleViewController!) } else if vc.isKind(of: UITabBarController.self) { let tabBarController = vc as! UITabBarController return UIWindow.getVisibleViewControllerFrom(vc: tabBarController.selectedViewController!) } else { if let presentedViewController = vc.presentedViewController { return UIWindow.getVisibleViewControllerFrom(vc: presentedViewController) } else { return vc; } } } }
你可以在AppDelegate中定义一个UIViewControllervariables,并且在每个viewWillAppear中设置variables为self(但是dianz的回答是最好的答案)。
override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) let appDel = UIApplication.sharedApplication().delegate as! AppDelegate appDel.currentVC = self }
在Swift 3中find可见的viewController
if let viewControllers = window?.rootViewController?.childViewControllers { let prefs = UserDefaults.standard if viewControllers[viewControllers.count - 1] is ABCController{ print("[ABCController] is visible") } }
此代码查找最后添加或最后一个活动控制器可见。
这个我在AppDelegate中用来查找活动视图控制器
你把代码放在哪里?
我在演示中尝试你的代码,我发现,如果你把代码放进去
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
将失败,因为关键窗口已经设置。
但是我把你的代码放在一些视图控制器中
override func viewDidLoad() {
它只是工作。