134

我需要一个根视图控制器的实例。

我尝试了这些方法:

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

返回:

另外,当我尝试获取一组控制器时:

NSArray *viewControllers = self.navigationController.viewControllers;

它只返回一个控制器,但它不是我的根视图控制器。

如果我尝试从导航控制器中获取:

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

返回:

任何想法为什么?我还能尝试获取我的根视图控制器的实例吗?

谢谢。

4

8 回答 8

251

如果您尝试访问rootViewController您在 appDelegate 中设置的内容。试试这个:

Objective-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
于 2012-09-14T05:17:11.347 回答
45

Objective-C

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

Swift 2.0

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

Swift 5

let viewController = UIApplication.shared.keyWindow?.rootViewController
于 2016-04-27T03:45:51.347 回答
10

正如@0x7fffffff在这里所建议的,如果你有 UINavigationController 它可以更容易做到:

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

The code in the answer above returns UINavigation controller (if you have it) and if this is what you need, you can use self.navigationController.

于 2013-05-22T22:18:54.683 回答
5

For Swift 5 and later, I recommend use this method:

UIApplication.shared.windows.last?.rootViewController

Use .last will return top view Controller is active.

.first sometimes doesn't work with libraries that require a window on top & actived.

For example: Admob . I have the ad not showing and find that I am calling the hidden window underneath when using sheet or fullscreenCover.

NOTE: View want to display ads required in NavigationView, if not, ads will be not run.

Example: NavigationView { View1() }

I hope it is useful.

于 2021-04-18T16:18:30.893 回答
4

Unless you have a good reason, in your root controller do this:

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

And when you want to notify it:

[[NSNotificationCenter defaultCenter] postNotificationName:@"ABCMyEvent"
                                                object:self];                
于 2014-02-16T10:31:04.257 回答
2

Swift 3

let rootViewController = UIApplication.shared.keyWindow?.rootViewController
于 2017-04-20T23:58:35.170 回答
1

Swift way to do it, you can call this from anywhere, it returns optional so watch out about that:

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

Its included as a standard function in:

https://github.com/goktugyil/EZSwiftExtensions

于 2015-11-24T04:35:14.070 回答
1

Swift 3: Chage ViewController withOut Segue and send AnyObject Use: Identity MainPageViewController on target ViewController

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

var mainPageNav = UINavigationController(rootViewController: mainPage)

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

or if you want to Change View Controller and send 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)  
于 2016-09-21T09:03:22.510 回答