web-dev-qa-db-ja.com

AppDelegateの現在のView Controller?

AppDelegateから現在のView Controllerを取得する方法はありますか? rootViewControllerがあることは知っていますが、それは私が探しているものではありません。

51
aoakenfo

AppDelegateにUINavigationControllerがある場合、そのプロパティ topViewController または visibleViewController を使用します

20
beryllium

アプリのルートビューコントローラーがUINavigationControllerである場合、これを行うことができます。

((UINavigationController*)appDelegate.window.rootViewController).visibleViewController;

同様に、それがUITabBarControllerであれば、これを行うことができます:

((UITabBarController*)appDelegate.window.rootViewController).selectedViewController;

もちろん、このような明示的なキャストは汚れています。強い型を使用して参照を自分でキャプチャする方が良いでしょう。

62
devios1

これは役立つかもしれません

- (UIViewController *)topViewController{
  return [self topViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
}

- (UIViewController *)topViewController:(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 topViewController:lastViewController];
  }

  UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
  return [self topViewController:presentedViewController];
}

Swiftバージョン:

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
    }
}

から取得: https://Gist.github.com/snikch/3661188

26
Daniel Ryan

拡張機能を作成:

extension UIApplication {
    class func topViewController(base: UIViewController? = UIApplication.sharedApplication().keyWindow?.rootViewController) -> UIViewController? {
        if let nav = base as? UINavigationController {
            return topViewController(nav.visibleViewController)
        }
        if let tab = base as? UITabBarController {
            let moreNavigationController = tab.moreNavigationController

            if let top = moreNavigationController.topViewController where top.view.window != nil {
                return topViewController(top)
            } else if let selected = tab.selectedViewController {
                return topViewController(selected)
            }
        }
        if let presented = base?.presentedViewController {
            return topViewController(presented)
        }
        return base
    }
}

使用法:

if let rootViewController = UIApplication.topViewController() {
    //do sth with root view controller
}
14
A.G

AppDelegateオブジェクトを取得します。

MyAppDelegate *tmpDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];

ベリリウムが示唆したように、UINavigationControllerのプロパティを使用して、現在のView Controllerにアクセスできます。

したがって、コードは次のようになります。

id myCurrentController = tmpDelegate.myNavigationController.topViewController;

または:

NSArray *myCurrentViewControllers = tmpDelegate.myNavigationController.viewControllers;
11
Quasar

次のようにpresentViewControllerを探すことで、rootViewControllerから現在のView Controllerを取得できます。

UIViewController *parentViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController;

while (parentViewController.presentedViewController != nil){
    parentViewController = parentViewController.presentedViewController;
}
UIViewController *currentViewController = parentViewController;

それは私と一緒に動作します。それが役に立てば幸い :)

8
MattZ

Swift Solution:

 self.window.rootViewController.presentedViewController. 

これで必要なものが得られます。

誰でもnotUINavigationControllerを使用しますが、デフォルトのView ControllerはUIViewControllerであり、どのView Controllerがアクティブであるかを確認できます(または表示)AppDelegateに以下を含む:

func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
    if let rootViewController = self.window!.rootViewController {
        if let presentedViewController = rootViewController.presentedViewController {
            return presentedViewController.supportedInterfaceOrientations()
        }
    } // Else current view controller is DefaultViewController

    return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}

ご覧のとおり、特定のView Controllerに対して異なるインターフェイスの向きをサポートするために、現在のView Controllerを確認しています。このメソッドを使用して特定のサポートを行うことに関心がある他の人は、特定の方向を必要とする各View Controllerに次のものを配置する必要があります。

override func supportedInterfaceOrientations() -> Int {
    return Int(UIInterfaceOrientationMask.All.rawValue)
} 

注:このコードはSwift 1.2

4
Clay Ellis

Swift 4 +構文のUIApplication拡張機能 A.Gのソリューション

public 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 {
            let moreNavigationController = tab.moreNavigationController

            if let top = moreNavigationController.topViewController, top.view.window != nil {
                return topViewController(base: top)
            } else if let selected = tab.selectedViewController {
                return topViewController(base: selected)
            }
        }
        if let presented = base?.presentedViewController {
            return topViewController(base: presented)
        }
        return base
    }
}

サンプル使用法:

if let rootViewController = UIApplication.topViewController() {
     //do something with rootViewController
}
2
Maverick

多くの場合、現在表示されているView Controllerを取得する必要があります。これは、現在のUINavigationControllerのスタックの最上位にあるView Controller、現在表示されているView Controllerなどを意味する可能性があります。そのため、ほとんどの時間を把握し、UIViewController拡張内で使用できるこの関数を書きました。

コードインSwift

_func currentViewController(
_ viewController: UIViewController? =
    UIApplication.shared.keyWindow?.rootViewController)
        -> UIViewController? {
    guard let viewController =
    viewController else { return nil }

    if let viewController =
        viewController as? UINavigationController {
        if let viewController =
            viewController.visibleViewController {
            return currentViewController(viewController)
        } else {
            return currentViewController(
                viewController.topViewController)
        }
    } else if let viewController =
            viewController as? UITabBarController {
        if let viewControllers =
            viewController.viewControllers,
            viewControllers.count > 5,
            viewController.selectedIndex >= 4 {
            return currentViewController(
                viewController.moreNavigationController)
        } else {
            return currentViewController(
                viewController.selectedViewController)
        }
    } else if let viewController =
            viewController.presentedViewController {
        return viewController
    } else if viewController.childViewControllers.count > 0 {
        return viewController.childViewControllers[0]
    } else {
        return viewController
    }
}
_

currentViewController()で呼び出します

0
Paolo Musolino