我的视图是UIViewController
(root)处理广告和UINavigationController
。在那个UINavigationController中,我有典型的控制器层。在我的自定义设置表视图控制器中,我有一个按钮与我联系以获得支持。当用户点击此按钮时,我创建了一个MFMailComposeViewController
并想要呈现它。我无法从设置表视图中显示它,因为它将位于我的广告下方,因此我需要引用根视图并从那里显示它。我已经尝试self.parentViewController.parentViewController
其中self是设置表视图,但这不起作用。我应该如何参考。直接引用根视图并将其传递给设置视图似乎是一个糟糕的设计。
答案 0 :(得分:79)
获取当前的keyWindow:
UIWindow *window = [UIApplication sharedApplication].keyWindow;
获取其rootViewController:
UIViewController *rootViewController = window.rootViewController;
注意:如果当前正在显示UIAlertView
,则会创建一个新窗口并将其指定为keyWindow。可能还有其他特殊情况,不会使您的应用程序窗口成为keyWindow。
答案 1 :(得分:33)
根据我的经验,这是获得rootViewController
:
[[[[UIApplication sharedApplication] delegate] window] rootViewController]
注意:如果处于有效UIAlert
或UIActionSheet
,您可以将警报或操作表作为关键窗口。
答案 2 :(得分:2)
使用app singleton。类似的东西:
如果作为根的viewController被命名为[[[UIApplication sharedApplication] delegate] rootViewController]
, rootViewController
应该得到它
答案 3 :(得分:1)
你总是可以通过一行代码来解决这个问题,但是我推荐这种Swift方式来实现它,你可以从任何地方调用它,它也会崩溃和bug安全:
/// 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
}
它作为标准函数包含在:
中答案 4 :(得分:-4)
获取UIApplication对象。 循环访问windows数组以查找keyWindow。 然后获取rootViewController属性。