如何找到根 UIViewController

Posted

技术标签:

【中文标题】如何找到根 UIViewController【英文标题】:How to find root UIViewController 【发布时间】:2011-05-11 18:14:50 【问题描述】:

我有一个处理广告的视图是UIViewController(根)和一个UINavigationController。在那个 UINavigationController 我有典型的控制器层。在我的自定义设置表视图控制器中,我有一个按钮可以联系我寻求支持。当用户单击此按钮时,我创建了一个 MFMailComposeViewController 并希望展示它。我无法从设置表视图中显示它,因为它将位于我的广告下方,因此我需要引用根视图并从那里显示它。我试过self.parentViewController.parentViewController self 是设置表视图,但这不起作用。我应该如何参考这个。必须直接引用根视图并将其传递给设置视图似乎是一个糟糕的设计。

【问题讨论】:

你试过self.navigationController吗?我不清楚您的视图层次结构是如何设置的。 【参考方案1】:

获取当前keyWindow:

UIWindow *window = [UIApplication sharedApplication].keyWindow;

获取它的rootViewController:

UIViewController *rootViewController = window.rootViewController;

注意:如果当前正在显示UIAlertView,则会创建一个新窗口并将其指定为keyWindow。可能还有其他例外情况不会让您的应用程序窗口成为 keyWindow。

【讨论】:

顺便说一句,这只适用于 4.0+。 UIWindow 在 4.0 之前没有 rootViewController 属性。 @Jesse 好点 - 我很高兴我不再需要支持那些古老的砖块;)。 是的,很糟糕。我会说它至少占了我 50% 的时间。 只是一个快速警告。如果在屏幕上使用 ui 警报调用它,这将不起作用。 @ChrisMitchelmore a UIAlert 会打开一个新窗口,并在显示时将其设为键窗口。【参考方案2】:

根据我的经验,这是获得rootViewController 的理想解决方案:

[[[[UIApplication sharedApplication] delegate] window] rootViewController]

注意:如果UIAlertUIActionSheet 处于活动状态,您将获得警报或操作表作为您的关键窗口。

【讨论】:

+1 这是唯一安全、可靠的方法。我花了很长时间才找到一个 alert + keyWindow 错误,这篇文章救了我! 第二个! keyWindow 方法(目前标记为正确答案)不可靠,因为关键窗口可以更改。 在 UIAlertView 期间使用 keyWindow 时也遇到了错误……谢谢!这是最好的使用方法。【参考方案3】:

使用应用单例。比如:

[[[UIApplication sharedApplication] delegate] rootViewController] 应该得到它,如果你作为根的 viewController 被命名为rootViewController

【讨论】:

【参考方案4】:

你总是可以用 1 行代码来解决这个问题,但我推荐这种 Swift 方法,你可以从任何地方调用它,它也是崩溃和错误安全的:

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

【讨论】:

【参考方案5】:

获取 UIApplication 对象。 循环遍历 windows 数组以找到 keyWindow。 然后获取 rootViewController 属性。

【讨论】:

以上是关于如何找到根 UIViewController的主要内容,如果未能解决你的问题,请参考以下文章

如何找到根元素值?

界面视图。如何快速找到根 SuperView?

PHP如何找到应用程序根?

如何找到的路径SSL证书文件

如何制作具有多个根树的圆形树

如何更改NextJS根路径页面