Jak zdobyć główny kontroler widoku?


109

Potrzebuję wystąpienia głównego kontrolera widoku.

Wypróbowałem te podejścia:

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

Zwroty: null :

Również gdy próbuję zdobyć tablicę kontrolerów:

NSArray *viewControllers = self.navigationController.viewControllers;

Zwraca tylko jeden kontroler, ale nie jest to mój główny kontroler widoku.

Jeśli spróbuję pobrać z kontrolera nawigacji:

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

Zwroty: null :

Jakieś pomysły, dlaczego? Co jeszcze mogę spróbować, aby uzyskać instancję mojego głównego kontrolera widoku?

Dzięki.


KeyWindow jest aktywnym oknem, na przykład kiedy pokazujesz UIAlertView, okno UIAlertView jest keyWindow, ale nie jest oknem AppDelegate.Jeśli chcesz pobrać rootViewController aplikacji, możesz użyć [[[UIApplication sharedApplication] delegata] okna] rootViewController ] jest lepiej.
无 夜 之 星辰

Odpowiedzi:


213

jeśli próbujesz uzyskać dostęp do rootViewControllerpliku ustawionego w pliku appDelegate. Spróbuj tego:

Cel C

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

Szybki

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

Szybki 3

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

Swift 4 i 4.2

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

Swift 5, 5.1 i 5.2

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

3
YourViewController * rootController = (YourViewController *) [[(YourAppDelegate *) [[UIApplication sharedApplication] delegat] window] rootViewController];
Craig Moore,

1
W Swift2 musisz użyć „let appDelegate = UIApplication.sharedApplication (). Delegate as! AppDelegate”, aby wymusić rozpakowanie
Jacky

Czy istnieje sposób, aby w ten sposób przypisać dwa kontrolery, aby można było pobrać dane z obu do zegarka?
Johnny Marin

1
To jest ratunek. Dziękuję Ci! Kilka miesięcy zajęło mi znalezienie tego kawałka pysznego kodu!
ItsMeDom

37

Cel C

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

Swift 2.0

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

Szybki 5

let viewController = UIApplication.shared.keyWindow?.rootViewController

3
To powinna być najlepsza odpowiedź. +1 Pozostałe odpowiedzi nie będą działać, jeśli musisz odwołać się do głównego kontrolera widoku z innej struktury, od której zależy Twoja główna aplikacja.
C. Tewalt,

10

Jak sugeruje tutaj przez @ 0x7fffffff, jeśli masz UINavigationController może łatwiej będzie zrobić:

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

Kod w powyższej odpowiedzi zwraca kontroler UINavigation (jeśli go masz) i jeśli tego potrzebujesz, możesz użyć self.navigationController.


5

Jeśli nie masz dobrego powodu, w kontrolerze głównym zrób to:

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

A kiedy chcesz to powiadomić:

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

2

Szybki 3

let rootViewController = UIApplication.shared.keyWindow?.rootViewController

1

Szybki sposób, możesz to zrobić z dowolnego miejsca, zwraca to opcjonalne, więc uważaj na to:

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

Jest to standardowa funkcja w:

https://github.com/goktugyil/EZSwiftExtensions


1

Swift 3: Chage ViewController withOut Segue i wyślij AnyObject Use: Identity MainPageViewController na docelowym ViewController

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

var mainPageNav = UINavigationController(rootViewController: mainPage)

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

lub jeśli chcesz zmienić kontrolera widoku i wysłać dane

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)  

Jesteś najlepszym kolesiem :)
bsm-2000
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.