Получение самого верхнего UIViewController

Если я нажимаю контроллеры просмотра и/или существующие контроллеры модального представления на UINavigationController, как я могу узнать, что является верхней частью самой UIViewController? Или в моем случае, я хочу знать, является ли какой-то UITableViewController самым большим или нет.

Я попытался использовать:

self.navigationController.topViewController == self

... но это не работает. Я предполагаю, что это не удается, потому что я представляю контроллеры modal view поверх него и что topViewController отслеживает только те представления, которые были нажаты на UINavigationController (в отличие от тех, которые были представлены модально).

Ответ 1

Вы хотите visibleViewController:

В настоящее время видимое представление может принадлежать либо контроллеру вида в верхней части стека навигации, либо контроллеру представления, который был представлен в виде модально.

Ответ 2

NSArray *viewContrlls=[[self navigationController] viewControllers];

[viewContrlls lastObject];

Ответ 3

Я знаю, что вопрос старый, но он по-прежнему популярен - поэтому я хотел бы опубликовать свое лучшее решение, которое обрабатывает различные подклассы UIViewController's. В то же время вы можете расширить функциональность этого метода с помощью собственных "коллекционных" контроллеров, таких как боковое меню.

extension UIWindow {

  var visibleViewController: UIViewController? {
    guard let rootViewController = rootViewController else {
      return nil
    }
    return visibleViewController(for: rootViewController)
  }

  private func visibleViewController(for controller: UIViewController) -> UIViewController {
    var nextOnStackViewController: UIViewController? = nil
    if let presented = controller.presentedViewController {
      nextOnStackViewController = presented
    } else if let navigationController = controller as? UINavigationController,
      let visible = navigationController.visibleViewController {
      nextOnStackViewController = visible
    } else if let tabBarController = controller as? UITabBarController,
      let visible = (tabBarController.selectedViewController ??
        tabBarController.presentedViewController) {
      nextOnStackViewController = visible
    }

    if let nextOnStackViewController = nextOnStackViewController {
      return visibleViewController(for: nextOnStackViewController)
    } else {
      return controller
    }
  }

}