Bagaimana cara mendapatkan pengontrol tampilan root?

109

Saya membutuhkan contoh pengontrol tampilan root.

Saya mencoba pendekatan tersebut:

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

Pengembalian: null :

Juga ketika saya mencoba mendapatkan berbagai pengontrol:

NSArray *viewControllers = self.navigationController.viewControllers;

Ini mengembalikan hanya satu pengontrol, tetapi itu bukan pengontrol tampilan root saya.

Jika saya mencoba mengambil dari pengontrol navigasi:

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

Pengembalian: null :

Ada ide mengapa? Apa lagi yang bisa saya coba untuk mendapatkan instance dari pengontrol tampilan root saya?

Terima kasih.

Anak jalanan
sumber
KeyWindow adalah jendela yang aktif, misalnya, ketika Anda menampilkan UIAlertView, jendela UIAlertView adalah keyWindow tetapi bukan jendela AppDelegate. Jika Anda ingin mendapatkan rootViewController aplikasi, mungkin gunakan jendela [[[UIApplication sharedApplication] delegate]] rootViewController ] lebih baik.
无 夜 之 星辰

Jawaban:

213

jika Anda mencoba mengakses yang rootViewControllerAnda setel di appDelegate. coba ini:

Objective-C

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

Cepat

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

Cepat 3

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

Cepat 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
janusfidel.dll
sumber
3
YourViewController * rootController = (YourViewController *) [[(YourAppDelegate *) [[[UIApplication sharedApplication] delegasi] jendela] rootViewController];
Craig Moore
1
Di Swift2, Anda harus menggunakan "let appDelegate = UIApplication.sharedApplication (). Delegate as! AppDelegate", untuk membuka paksa
Jacky
Adakah cara agar dua pengontrol ditetapkan dengan cara ini sehingga Anda dapat menarik data dari keduanya ke jam tangan?
Johnny Marin
1
Ini adalah penyelamat. Terima kasih! Butuh waktu berbulan-bulan untuk menemukan kode lezat ini!
ItsMeDom
37

Objective-C

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

Swift 2.0

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

Cepat 5

let viewController = UIApplication.shared.keyWindow?.rootViewController
Chamath Jeevan
sumber
3
Ini harus menjadi jawaban teratas. +1 Jawaban lain tidak akan berfungsi jika Anda perlu merujuk pengontrol tampilan root dari kerangka kerja berbeda yang bergantung pada aplikasi utama Anda.
C. Tewalt
10

Seperti yang disarankan di sini oleh @ 0x7fffffff, jika Anda memiliki UINavigationController, lebih mudah melakukannya:

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

Kode dalam jawaban di atas mengembalikan pengontrol UINavigation (jika Anda memilikinya) dan jika ini yang Anda butuhkan, Anda dapat menggunakannya self.navigationController.

esp
sumber
5

Kecuali jika Anda memiliki alasan yang bagus, lakukan ini di pengontrol root:

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

Dan saat Anda ingin memberi tahu:

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

Cepat 3

let rootViewController = UIApplication.shared.keyWindow?.rootViewController
cybermach
sumber
1

Cara cepat untuk melakukannya, Anda dapat memanggil ini dari mana saja, ini mengembalikan opsional jadi hati-hati tentang itu:

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

Ini termasuk sebagai fungsi standar dalam:

https://github.com/goktugyil/EZSwiftExtensions

Esqarrouth
sumber
1

Swift 3: Chage ViewController withOut Segue dan kirim AnyObject Use: Identity MainPageViewController pada target ViewController

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

var mainPageNav = UINavigationController(rootViewController: mainPage)

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

atau jika Anda ingin Mengubah Tampilan Pengontrol dan mengirim Data

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)  
pengguna6857463
sumber
Anda adalah pria terbaik :)
bsm-2000