ルートビューコントローラーを取得する方法?


109

ルートビューコントローラーのインスタンスが必要です。

私はそれらのアプローチを試しました:

UIViewController *rootViewController = (UIViewController*)[[[UIApplication sharedApplication] keyWindow] rootViewController];

戻り値: null

また、コントローラの配列を取得しようとすると:

NSArray *viewControllers = self.navigationController.viewControllers;

1つのコントローラーのみを返しますが、ルートビューコントローラーではありません。

ナビゲーションコントローラーから取得しようとした場合:

UIViewController *root = (UIViewController*)[self.navigationController.viewControllers objectAtIndex:0];

戻り値: null

何かアイデアはありますか?ルートビューコントローラーのインスタンスを取得するために他に何ができるでしょうか?

ありがとう。


keyWindowはアクティブなウィンドウです。たとえば、UIAlertViewを表示する場合、UIAlertViewのウィンドウはkeyWindowですが、AppDelegateのウィンドウではありません。アプリケーションのrootViewControllerを取得する場合は、[[[UIApplication sharedApplication] delegate] window] rootViewController ] 優れている。
夜之星辰

回答:


213

rootViewControllerappDelegateで設定したにアクセスしようとしている場合。これを試して:

Objective-C

YourViewController *rootController = (YourViewController*)[[(YourAppDelegate*)
                                   [[UIApplication sharedApplication]delegate] window] rootViewController];

迅速

let appDelegate  = UIApplication.sharedApplication().delegate as AppDelegate
let viewController = appDelegate.window!.rootViewController as YourViewController

スウィフト3

let appDelegate  = UIApplication.shared.delegate as! AppDelegate
let viewController = appDelegate.window!.rootViewController as! YourViewController

Swift 4および4.2

let viewController = UIApplication.shared.keyWindow!.rootViewController as! YourViewController

Swift 5、5.1、5.2

let viewController = UIApplication.shared.windows.first!.rootViewController as! YourViewController

3
YourViewController * rootController =(YourViewController *)[[(YourAppDelegate *)[[UIApplication sharedApplication] delegate] window] rootViewController];
クレイグムーア

1
Swift2では、アンラップを強制するには、「let appDelegate = UIApplication.sharedApplication()。delegate as!AppDelegate」を使用する必要があります
Jacky

この方法で2つのコントローラーを割り当てて、両方から時計にデータをプルする方法はありますか?
ジョニーマリン

1
これは命の恩人です。ありがとうございました!このおいしいコードを見つけるのに何ヶ月もかかりました!
ItMeDom

37

Objective-C

UIViewController *controller = [UIApplication sharedApplication].keyWindow.rootViewController;

Swift 2.0

let viewController = UIApplication.sharedApplication().keyWindow?.rootViewController

スウィフト5

let viewController = UIApplication.shared.keyWindow?.rootViewController

3
これが一番の答えになるはずです。+1メインアプリが依存している別のフレームワークからルートビューコントローラーを参照する必要がある場合、他の回答は機能しません。
C. Tewalt 2016

10

ここで@ 0x7fffffffによって提案されているように、UINavigationControllerがある場合は簡単に実行できます。

YourViewController *rootController =
    (YourViewController *)
        [self.navigationController.viewControllers objectAtIndex: 0];

上記の答えのコードはUINavigationコントローラー(ある場合)を返し、これが必要な場合はを使用できますself.navigationController


5

正当な理由がない限り、ルートコントローラで次のようにします。

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(onTheEvent:)
                                             name:@"ABCMyEvent"
                                           object:nil];

そして、あなたがそれを通知したいとき:

[[NSNotificationCenter defaultCenter] postNotificationName:@"ABCMyEvent"
                                                object:self];                


1

それを行う迅速な方法、これはどこからでも呼び出すことができ、オプションを返すので、それについては注意してください。

/// EZSwiftExtensions - Gives you the VC on top so you can easily push your popups
var topMostVC: UIViewController? {
    var presentedVC = UIApplication.sharedApplication().keyWindow?.rootViewController
    while let pVC = presentedVC?.presentedViewController {
        presentedVC = pVC
    }

    if presentedVC == nil {
        print("EZSwiftExtensions Error: You don't have any views set. You may be calling them in viewDidLoad. Try viewDidAppear instead.")
    }
    return presentedVC
}

その標準関数として含まれています:

https://github.com/goktugyil/EZSwiftExtensions


1

Swift 3:ViewController withOut Segueを送信してAnyObject送信する使用:ターゲットViewControllerのIdentity MainPageViewController

let mainPage = self.storyboard?.instantiateViewController(withIdentifier: "MainPageViewController") as! MainPageViewController

var mainPageNav = UINavigationController(rootViewController: mainPage)

self.present(mainPageNav, animated: true, completion: nil)

または、View Controllerを変更してデータを送信したい場合

let mainPage = self.storyboard?.instantiateViewController(withIdentifier: "MainPageViewController") as! MainPageViewController

let dataToSend = "**Any String**" or  var ObjectToSend:**AnyObject** 

mainPage.getData = dataToSend 

var mainPageNav = UINavigationController(rootViewController: mainPage)

self.present(mainPageNav, animated: true, completion: nil)  

あなたは最高の男です:)
bsm-2000 '15
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.