如何获得根视图控制器?


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]委托] window] rootViewController ] 更好。
无夜之星辰

Answers:


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

迅捷4和4.2

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

雨燕5&5.1&5.2

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

3
YourViewController * rootController =(YourViewController *)[[((YourAppDelegate *)[[UIApplication sharedApplication]代理]窗口] rootViewController];
Craig Moore

1
在Swift2中,您必须使用“ let appDelegate = UIApplication.sharedApplication()。delegate as!AppDelegate”来强制展开
Jacky

有没有办法以这种方式分配两个控制器,以便您可以将数据从两个控制器中提取到手表?
约翰尼·马林

1
这是一个救命稻草。谢谢!花了我几个月的时间来找到这段美味的代码!
ItsMeDom

37

目标C

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

雨燕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控制器(如果有),并且如果需要,可以使用self.navigationController


5

除非您有充分的理由,否则请在根控制器中执行以下操作:

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

当您想通知它时:

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

2

迅捷3

let rootViewController = UIApplication.shared.keyWindow?.rootViewController

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:在没有Segue的情况下 使用Chage ViewController并发送AnyObject使用:目标ViewController上的Identity MainPageViewController

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.