วิธีรับตัวควบคุมมุมมองรูท


109

ฉันต้องการอินสแตนซ์ของตัวควบคุมมุมมองรูท

ฉันลองวิธีการเหล่านั้น:

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

ผลตอบแทน: null :

นอกจากนี้เมื่อฉันพยายามรับอาร์เรย์ของคอนโทรลเลอร์:

NSArray *viewControllers = self.navigationController.viewControllers;

ส่งคืนคอนโทรลเลอร์เพียงตัวเดียว แต่ไม่ใช่ตัวควบคุมมุมมองรูทของฉัน

หากฉันพยายามใช้ตัวควบคุมการนำทาง:

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

ผลตอบแทน: null :

ความคิดใด ๆ ทำไม? ฉันจะลองใช้อินสแตนซ์ของตัวควบคุมมุมมองรูทของฉันได้อย่างไร

ขอบคุณ.


keyWindow คือหน้าต่างที่ใช้งานอยู่ตัวอย่างเช่นเมื่อคุณแสดง UIAlertView หน้าต่างของ UIAlertView คือ keyWindow แต่ไม่ใช่หน้าต่างของ AppDelegate หากคุณต้องการรับ rootViewController ของแอปพลิเคชันอาจใช้ [[[UIApplication sharedApplication] delegate] window] rootViewController ] จะดีกว่า.
无夜之星辰

คำตอบ:


213

หากคุณพยายามเข้าถึงสิ่งที่rootViewControllerคุณตั้งไว้ใน appDelegate ของคุณ ลองสิ่งนี้:

วัตถุประสงค์ -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] rootViewController];
Craig Moore

1
ใน Swift2 คุณต้องใช้ "let appDelegate = UIApplication.sharedApplication (). delegate as! appDelegate" เพื่อบังคับให้แกะออก
Jacky

มีวิธีใดบ้างที่จะกำหนดตัวควบคุมสองตัวในลักษณะนี้เพื่อให้คุณสามารถดึงข้อมูลจากทั้งสองไปยังนาฬิกาได้
Johnny Marin

1
นี่คือเครื่องช่วยชีวิต ขอบคุณ! ฉันใช้เวลาหลายเดือนเพื่อค้นหารหัสอร่อยชิ้นนี้!
ItsMeDom

37

วัตถุประสงค์ -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

10

เป็นข้อเสนอแนะที่นี่โดย @ 0x7FFFFFFF ถ้าคุณมี UINavigationController มันอาจจะง่ายต่อการทำ:

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

รหัสในคำตอบด้านบนจะแสดงผล UINavigation controller (ถ้าคุณมี) และหากนี่คือสิ่งที่คุณต้องการคุณสามารถ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: Chage ViewController withOut Segue และส่ง AnyObject Use: Identity MainPageViewController บน Target ViewController

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.