Как получить корневой контроллер?

Мне нужен экземпляр контроллера корневого представления.

Я попробовал эти подходы:

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

Возвращает: null:

Также, когда я пытаюсь получить массив контроллеров:

NSArray *viewControllers = self.navigationController.viewControllers;

Он возвращает только один контроллер, но это не мой корневой контроллер представления.

Если я попытаюсь взять с навигационного контроллера:

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

Возвращает: null:

Есть идеи почему? Что еще я могу попытаться получить экземпляр моего корневого контроллера представления?

Благодарю.

Ответ 1

если вы пытаетесь получить доступ к rootViewController, установленному в appDelegate. попробуйте это:

Objective-C

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

Swift

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

Ответ 2

В ручном режиме доступа к контроллеру корневого представления.

Цель C

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

Swift 2.0

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

Ответ 3

Objective-C формат:

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

Формат Swift 2:

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

Формат Swift 3 и 4:

let objViewController =  UIApplication.shared.keyWindow?.rootViewController

Ответ 4

Как было предложено здесь с помощью @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];                

Ответ 6

Быстрый способ сделать это, вы можете вызывать это из любого места, он возвращается дополнительно, поэтому следите за этим:

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

Ответ 7

Swift 3: Chage ViewController withOut Segue и отправить AnyObject Использование: Identity MainPageViewController в целевом ViewController

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

var mainPageNav = UINavigationController(rootViewController: mainPage)

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

, или если вы хотите изменить контроллер просмотра и отправить данные

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)  

Ответ 8

Swift 3

let rootViewController = UIApplication.shared.keyWindow?.rootViewController

Ответ 9

Swift 3:

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

Ответ 10

let view:UIView = UIView()

view.frame = CGRect(x:0, y:0, width:UIApplication.shared.statusBarFrame.width, height:UIApplication.shared.statusBarFrame.height

view.backgroundColor = UIColor.init(named: "yourColor")
UIApplication.shared.keyWindow!.rootViewController?.view.addSubview(view)