Получить самый лучший UIViewController
Я не могу, кажется, получить самый верхний UIViewController
текст UINavigationController
. Вот что у меня есть до сих пор:
UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(vc, animated: true, completion: nil)
однако, похоже, он ничего не делает. The keyWindow
и rootViewController
похоже, что значения не равны нулю, поэтому необязательная цепочка не должна быть проблемой.
спасибо заранее!
Примечание: это плохая идея, чтобы сделать что-то подобное. Это нарушает шаблон MVC.
12 ответов
presentViewController
показывает контроллер представления. Он не возвращает контроллер вида. Если вы не используете UINavigationController
, вы, вероятно, искали presentedViewController
и вам нужно будет начать с корня и перебирать представленные представления.
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)
}
для swift4, чтобы найти самый верхний viewController
extension UIApplication {
class func getTopMostViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return getTopMostViewController(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController {
return getTopMostViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return getTopMostViewController(base: presented)
}
return base
}
}
как использовать
if let topVC = UIApplication.getTopMostViewController() {
topVC.view.addSubview(forgotPwdView)
}
основываясь на ответе 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 это, и вот версия swift 3. Это в основном то же самое, но у него отсутствовала фигурная скобка, и некоторые имена синтаксиса/переменной/метода изменились. Вот оно!
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)")
}
используйте этот код, чтобы найти самый верхний UIViewController
func getTopViewController() -> UIViewController? {
var topController: UIViewController? = UIApplication.shared.keyWindow?.rootViewController
while topController?.presentedViewController != nil {
topController = topController?.presentedViewController
}
return topController
}
вы можете определить переменную UIViewController в AppDelegate, и в каждом viewWillAppear установите переменную в self.(однако dianz ответ является лучшим ответом.)
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
let appDel = UIApplication.sharedApplication().delegate as! AppDelegate
appDel.currentVC = self
}
на основе 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;
}
}
}
}
куда вы положили код?
Я попробую ваш код в моем демо, я узнал, если вы поместите код в
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
не получится, так как окна ключ настройки.
но я поместил ваш код в некоторый контроллер вида
override func viewDidLoad() {
Он просто работает.
чтобы найти видимый viewController в Swift 3
if let viewControllers = window?.rootViewController?.childViewControllers {
let prefs = UserDefaults.standard
if viewControllers[viewControllers.count - 1] is ABCController{
print("[ABCController] is visible")
}
}
этот код находит последний добавленный или последний активный контроллер.
Это я использовал в AppDelegate, чтобы найти активный контроллер вида
https://gist.github.com/db0company/369bfa43cb84b145dfd8 Я сделал несколько тестов на ответы и комментарии на этом сайте. Для меня, следующие работы
extension UIViewController {
func topMostViewController() -> UIViewController {
if let presented = self.presentedViewController {
return presented.topMostViewController()
}
if let navigation = self as? UINavigationController {
return navigation.visibleViewController?.topMostViewController() ?? navigation
}
if let tab = self as? UITabBarController {
return tab.selectedViewController?.topMostViewController() ?? tab
}
return self
}
}
extension UIApplication {
func topMostViewController() -> UIViewController? {
return self.keyWindow?.rootViewController?.topMostViewController()
}
}
затем получите верхний viewController по:
UIApplication.shared.topMostViewController()