web-dev-qa-db-ja.com

最上位のUIViewControllerを取得する

View Controllerをプッシュしたり、UINavigationControllerにモーダルView Controllerを表示した場合、一番上にあるUIViewControllerを見つけるにはどうすればよいですか?または、私の場合、特定のUITableViewControllerが最上位かどうかを知りたいです。

私は使用してみました:

self.navigationController.topViewController == self

...しかし、これは機能しません。私はその上にモーダルビューコントローラを提示しているために失敗していると推測しています、そしてtopViewControllerはどのビューがUINavigationControllerにプッシュされたかを追跡するだけですモーダルで提示された)。

55
Senseful

visibleViewControllerが必要です:

現在表示されているビューは、ナビゲーションスタックの最上部にあるView Controllerまたはモーダルで表示されたView Controllerのいずれかに属します。

94
Adam Ernst
NSArray *viewContrlls=[[self navigationController] viewControllers];

[viewContrlls lastObject];
21
Swastik

質問は古いことは知っていますが、まだ人気があります。だからこそ、さまざまな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
    }
  }

}
0