如何获得root视图控制器?

Str*_*boy 101 objective-c uiviewcontroller uinavigationcontroller ios5 swift

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

我试过这些方法:

UIViewController *rootViewController = (UIViewController*)[[[UIApplication sharedApplication] keyWindow] rootViewController];
Run Code Online (Sandbox Code Playgroud)

返回: null:

当我尝试获得一组控制器时:

NSArray *viewControllers = self.navigationController.viewControllers;
Run Code Online (Sandbox Code Playgroud)

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

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

UIViewController *root = (UIViewController*)[self.navigationController.viewControllers objectAtIndex:0];
Run Code Online (Sandbox Code Playgroud)

返回: null:

有什么想法吗?还有什么我可以尝试获取我的根视图控制器的实例?

谢谢.

jan*_*del 183

如果您尝试访问rootViewControllerappDelegate中设置的内容.试试这个:

Objective-C的

YourViewController *rootController = (YourViewController*)[[(YourAppDelegate*)
                                   [[UIApplication sharedApplication]delegate] window] rootViewController];
Run Code Online (Sandbox Code Playgroud)

迅速

let appDelegate  = UIApplication.sharedApplication().delegate as AppDelegate
let viewController = appDelegate.window!.rootViewController as YourViewController
Run Code Online (Sandbox Code Playgroud)

斯威夫特3

let appDelegate  = UIApplication.shared.delegate as! AppDelegate
let viewController = appDelegate.window!.rootViewController as! YourViewController
Run Code Online (Sandbox Code Playgroud)

斯威夫特4

let viewController = UIApplication.shared.keyWindow!.rootViewController as! YourViewController
Run Code Online (Sandbox Code Playgroud)

  • YourViewController*rootController =(YourViewController*)[[(YourAppDelegate*)[[UIApplication sharedApplication]委托]窗口] rootViewController]; (3认同)

Cha*_*van 35

以简短的方式访问根视图控制器.

目标C.

UIViewController *controller = [UIApplication sharedApplication].keyWindow.rootViewController;
Run Code Online (Sandbox Code Playgroud)

Swift 2.0

let viewController =  UIApplication.sharedApplication().keyWindow?.rootViewController
Run Code Online (Sandbox Code Playgroud)

  • 这应该是最好的答案.+1如果您需要从主应用程序所依赖的其他框架引用根视图控制器,则其他答案将不起作用. (3认同)
  • 值得指出的是,keyWindow 在 iOS13 中已被弃用 (3认同)

Jay*_*bey 17

Objective-C格式:

UIViewController *objViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
Run Code Online (Sandbox Code Playgroud)

Swift 2格式:

let objViewController =  UIApplication.sharedApplication().keyWindow?.rootViewController
Run Code Online (Sandbox Code Playgroud)

Swift 3和4格式:

let objViewController =  UIApplication.shared.keyWindow?.rootViewController
Run Code Online (Sandbox Code Playgroud)


esp*_*esp 10

作为建议在这里通过@ 0x7FFFFFFF的,如果你有UINavigationController的它可以更容易做到:

YourViewController *rootController =
    (YourViewController *)
        [self.navigationController.viewControllers objectAtIndex: 0];
Run Code Online (Sandbox Code Playgroud)

上面答案中的代码返回UINavigation控制器(如果有的话),如果这是你需要的,你可以使用self.navigationController.


Thi*_*ang 10

对于Swift 5 及更高版本,我建议使用此方法:

UIApplication.shared.windows.last?.rootViewController
Run Code Online (Sandbox Code Playgroud)

使用.last将返回顶视图控制器处于活动状态。

.first有时不适用于需要顶部窗口并处于活动状态的库。

例如:Admob。我的广告没有显示,并发现在使用工作表或全屏封面时我正在调用下面的隐藏窗口。

注意:NavigationView 中的 View 需要显示广告,如果没有,广告将不会运行。

示例:NavigationView { View1() }

我希望它有用。

  • UIApplication.shared.windows.last!.rootViewController 已在 iOS 15.0 中弃用 (2认同)

Dim*_*a G 6

iOS 15

随着场景和一些 API 被弃用(例如UIApplication.shared.keyWindow),我发现的最通用的方法是:

let scene = UIApplication.shared.connectedScenes
    .first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene

let rootViewController = scene?
    .windows.first(where: { $0.isKeyWindow })?
    .rootViewController
Run Code Online (Sandbox Code Playgroud)

注意:如果您的应用程序真正支持多个窗口/场景,则意味着您有多个“根视图控制器”,并且此代码不适合您:)


wis*_*sty 5

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

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(onTheEvent:)
                                             name:@"ABCMyEvent"
                                           object:nil];
Run Code Online (Sandbox Code Playgroud)

当你想要通知它时:

[[NSNotificationCenter defaultCenter] postNotificationName:@"ABCMyEvent"
                                                object:self];                
Run Code Online (Sandbox Code Playgroud)