我现在遇到了几个案例,它们可以方便地找到“最顶层”的视图控制器(负责当前视图的控制器),但还没有找到办法 .
基本上挑战是:假设一个是 executing in a class that is not a view controller (或视图) [and does not have the address of an active view] 并且还没有传递最顶层视图控制器的地址(或者说,导航控制器的地址),是否可以找到该视图控制器? (如果是这样,怎么样?)
或者,如果失败了,是否有可能找到最顶层的视图?
30 回答
iOS 4在UIWindow上引入了rootViewController属性:
您需要在创建视图控制器后自己设置它 .
我认为你需要一个接受的答案和@ fishstix的组合
Swift 3.0+
要完成JonasG的answer(在遍历时遗漏了标签栏控制器),这是我返回当前可见视图控制器的版本:
一个完整的非递归版本,负责不同的场景:
视图控制器正在呈现另一个视图
视图控制器是
UINavigationController
视图控制器是
UITabBarController
Objective-C
Swift 4+
使用扩展获取Swift的最顶层视图控制器
Code:
Usage:
要完成Eric的answer(他们在浏览时遗漏了弹出窗口,导航控制器,tabbarcontrollers,视图控制器作为子视图添加到其他视图控制器),这是我返回当前可见视图控制器的版本:
================================================== ===================
================================================== ===================
现在你需要做的就是获得最顶层的视图控制器,调用上面的方法如下:
这个答案包括
childViewControllers
并维护一个干净和可读的实现 .我最近在我的一个项目中得到了这种情况,当网络状态发生变化时,需要显示控制器显示的通知视图以及类型(UINavigationController,经典控制器或自定义视图控制器) .
所以我juste发布了我的代码,这很简单并且实际上基于协议,因此它对于每种类型的容器控制器都是灵活的 . 它似乎与最后的答案有关,但是以一种非常灵活的方式 .
你可以在这里获取代码:PPTopMostController
并获得最高控制器使用
这是对Eric的回答的改进:
_topMostController(UIViewController *cont)
是辅助函数 .现在您需要做的就是调用
topMostController()
并返回最顶层的UIViewController!这是我对此的看法 . 感谢@Stakenborg指出了跳过让UIAlertView成为最顶级控制器的方法
对于最新的Swift版本:
创建一个文件,将其命名为
UIWindowExtension.swift
并粘贴以下代码段:在任何地方使用它:
Swift中
UIApplication
的简单扩展:NOTE:
It cares about moreNavigationController within UITabBarController
用法简单:
这对我有用 .
我发现有时控制器在关键窗口上是零,因为keyWindow是一些操作系统,如警报等 .
扩展@ Eric的答案,你需要注意keyWindow实际上是你想要的窗口 . 例如,如果您在警报视图中点击某些内容后尝试使用此方法,则keyWindow实际上将成为警报的窗口,这无疑会给您带来问题 . 当通过警报处理深度链接并导致SIGABRT没有堆栈跟踪时,这发生在我的野外 . 要调试的总婊子 .
这是我现在使用的代码:
随意从这个问题的其他答案中检索您喜欢的顶视图控制器的风格 .
替代Swift解决方案:
又一个Swift解决方案
这个解决方案是最完整的 . 它需要考虑:UINavigationController UIPageViewController UITabBarController和顶视图控制器中最顶层的视图控制器
这个例子是在Swift 3中 .
有3个重载
伟大的解决方案Swift,在AppDelegate中实现
我认为大多数答案都完全忽略
UINavigationViewController
,所以我通过以下实现处理了这个用例 .不确定这是否有助于你通过找到最顶层的视图控制器来完成你想要完成的任务,但我试图提出一个新的视图控制器,但如果我的根视图控制器已经有一个模态对话框,它将被阻止,所以我将使用此代码循环到所有模态视图控制器的顶部:
迅速:
用法:
下面两个函数可以帮助在Stack of view控制器上找到topViewController . 您可能需要稍后进行自定义,但是对于此代码来说,了解topViewController或viewControllers堆栈的概念非常棒 .
您可以使用[viewController Class]方法找出viewController的类类型 .
另一个Swift解决方案
很多这些答案都是不完整的 . 虽然这是在Objective-C中,但这是我现在可以组合在一起的所有这些的最佳编译,作为非递归块:
...... Link to gist ,如果它被修改:https://gist.github.com/benguild/0d149bb3caaabea2dac3d2dca58c0816
... Code 供参考/比较:
如果根控制器是导航控制器,找到顶部可见控制器的正确方法是:
这是UINavigationController.h的摘录:
这非常适合从任何根视图控件中查找顶部viewController 1
你可以通过使用找到最顶层的视图控制器
另一种解决方案依赖于响应者链,根据第一响应者的不同,响应者链可能会或可能不会起作用:
Get the first responder .
Get the UIViewController associated with that first responder .
伪代码示例: