Wie bekomme ich Root View Controller?


109

Ich benötige eine Instanz von Root View Controller.

Ich habe diese Ansätze ausprobiert:

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

Rückgabe: null :

Auch wenn ich versuche, ein Array von Controllern zu bekommen:

NSArray *viewControllers = self.navigationController.viewControllers;

Es wird nur ein Controller zurückgegeben, aber es ist nicht mein Root-View-Controller.

Wenn ich versuche, vom Navigationscontroller zu nehmen:

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

Rückgabe: null :

Irgendwelche Ideen warum? Was könnte ich sonst noch versuchen, eine Instanz meines Root View Controllers zu erhalten?

Vielen Dank.


Das keyWindow ist das aktive Fenster. Wenn Sie beispielsweise eine UIAlertView anzeigen, ist das Fenster der UIAlertView das keyWindow, aber nicht das Fenster des AppDelegate. Wenn Sie den rootViewController der Anwendung abrufen möchten, verwenden Sie möglicherweise das [[[UIApplication sharedApplication] delegate] -Fenster] rootViewController ] ist besser.
夜 之 星辰

Antworten:


213

Wenn Sie versuchen, auf die rootViewControllerin Ihrem AppDelegate festgelegten Werte zuzugreifen. Versuche dies:

Ziel c

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

Schnell

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

Swift 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] -Fenster] rootViewController];
Craig Moore

1
In Swift2 müssen Sie "let appDelegate = UIApplication.sharedApplication (). Delegate as! AppDelegate" verwenden, um das Auspacken zu erzwingen
Jacky

Gibt es eine Möglichkeit, zwei Controller auf diese Weise zuzuweisen, damit Sie Daten von beiden auf die Uhr ziehen können?
Johnny Marin

1
Dies ist ein Lebensretter. Danke dir! Ich habe Monate gebraucht, um diesen köstlichen Code zu finden!
ItsMeDom

37

Ziel c

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

Swift 2.0

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

Swift 5

let viewController = UIApplication.shared.keyWindow?.rootViewController

3
Dies sollte die beste Antwort sein. +1 Die anderen Antworten funktionieren nicht, wenn Sie den Root-View-Controller aus einem anderen Framework referenzieren müssen, von dem Ihre Haupt-App abhängig ist.
C. Tewalt

10

Wie hier von @ 0x7fffffff vorgeschlagen, kann es einfacher sein, UINavigationController zu verwenden:

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

Der Code in der obigen Antwort gibt den UINavigation-Controller zurück (falls vorhanden). Wenn Sie diesen benötigen, können Sie ihn verwenden self.navigationController.


5

Wenn Sie keinen guten Grund haben, gehen Sie in Ihrem Root-Controller folgendermaßen vor:

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

Und wenn Sie es benachrichtigen möchten:

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

2

Swift 3

let rootViewController = UIApplication.shared.keyWindow?.rootViewController

1

Schneller Weg, Sie können dies von überall aus aufrufen. Es wird optional zurückgegeben. Achten Sie also darauf:

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

Es ist als Standardfunktion enthalten in:

https://github.com/goktugyil/EZSwiftExtensions


1

Swift 3: Chage ViewController ohne Segue und sende AnyObject Verwendung: Identity MainPageViewController auf dem Ziel-ViewController

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

var mainPageNav = UINavigationController(rootViewController: mainPage)

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

oder wenn Sie den View Controller ändern und Daten senden möchten

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)  

Du bist der beste Typ :)
bsm-2000
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.