在处理 URL Router 跳转的时候,我们经常需要得到 当前最上层的视图控制器 和 当前最上层的导航控制器 来进行视图跳转或者方法调用。

- (UIViewController *)currentViewController
{
UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
UIViewController *vc = keyWindow.rootViewController;
while (vc.presentedViewController)
{
vc = vc.presentedViewController; if ([vc isKindOfClass:[UINavigationController class]])
{
vc = [(UINavigationController *)vc visibleViewController];
}
else if ([vc isKindOfClass:[UITabBarController class]])
{
vc = [(UITabBarController *)vc selectedViewController];
}
}
return vc;
} - (UINavigationController *)currentNavigationController
{
return [self currentViewController].navigationController;
} /////////////////////////////////////////////////////////////////////////
2个只读属性:
presentedViewController:The view controller that is presented by this view controlller(read-only),被本视图控制器present出来的的视图控制器 presentingViewController:The view controller that presented this view controller. (read-only),present出来本视图控制器的视图控制器 如A-->弹出B, 则A.presentedViewController = B
B.presentingViewController = A dismissViewControllerAnimated:YES
Dismisses the view controller that was presented modally by the view controller.
也就是在在A上调该方法,dismiss掉A弹出的vc
如果在B上调,会调用presenting view的该方法,即A的该方法,很绕啊。

UINavigationController 中有visibleViewControllertopViewController

  • visibleViewController 当前显示的控制器
  • topViewController 是某个导航栈的栈顶视图
  • visibleViewController跟导航栈没有关系,只是当前显示的控制器,也就是说任意一个导航的visibleViewController所返回的值应该是一样的,
  • topViewController 是某个导航栈的栈顶视图,和导航控制器相关
    换句话说如果在仅有一个导航栈上,visibleViewControllertopViewController应该是没有区别得。

方法一 : 获取当前显示的控制器 UIWindow (Visible)

 - (UIViewController *)visibleViewController {
UIViewController *rootViewController =[[[[UIApplication sharedApplication] delegate] window] rootViewController];
return [UIWindow getVisibleViewControllerFrom:rootViewController];
}
+ (UIViewController *) getVisibleViewControllerFrom:(UIViewController *) vc {
if ([vc isKindOfClass:[UINavigationController class]]) {
return [UIWindow getVisibleViewControllerFrom:[((UINavigationController *) vc) visibleViewController]];
} else if ([vc isKindOfClass:[UITabBarController class]]) {
return [UIWindow getVisibleViewControllerFrom:[((UITabBarController *) vc) selectedViewController]];
} else {
if (vc.presentedViewController) {
return [UIWindow getVisibleViewControllerFrom:vc.presentedViewController];
} else {
return vc;
}
} }

方法二 :

- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
if ([rootViewController isKindOfClass:[UITabBarController class]]) {
UITabBarController* tabBarController = (UITabBarController*)rootViewController;
return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
} else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController* navigationController = (UINavigationController*)rootViewController;
return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
} else if (rootViewController.presentedViewController) {
UIViewController* presentedViewController = rootViewController.presentedViewController;
return [self topViewControllerWithRootViewController:presentedViewController];
} else {
return rootViewController;
} }

值得注意的是

    • [[[UIApplication sharedApplication] keyWindow] rootViewController]有时为nil 比如当页面有菊花在转的时候,这个rootViewController就为nil;
    • 所以使用[[[[UIApplication sharedApplication] delegate] window] rootViewController]
      或者[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController]

    • presentedViewController 和presentingViewController
      当A弹出B
      A.presentedViewController=B
      B.presentingViewController=A



当前最上层的视图控制器vc 和 当前最上层的导航控制器nav的更多相关文章

  1. iOS开发UINavigation——导航控制器UINavigationController

    iOS开发UINavigation系列一——导航栏UINavigtionBar摘要iOS中的导航条可以附着于导航控制器之中使用,也可以在controller中单独使用,这篇博客,主要讨论有关导航栏的使 ...

  2. IOS之导航控制器

    UINavigationController是用于构建分层应用程序的主要工具,主要采用栈形式来实现视图.任何类型的视图控制器都可放入栈中.在设计导航控制器时需要指定根视图即用户看到的第一个视图.根视图 ...

  3. UINavigationController导航控制器初始化 导航控制器栈的push和pop跳转理解

    (1)导航控制器初始化的时候一般都有一个根视图控制器,导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最下面,最后进去的在最上面.在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界 ...

  4. IOS开发UI篇—导航控制器属性和基本使用

    IOS开发UI篇—导航控制器属性和基本使用 一.导航控制器的一些属性和基本使用 1.把子控制器添加到导航控制器中的四种方法 (1) 1.创建一个导航控制器 UINavigationController ...

  5. iOS开发-21UINavigationController导航控制器初始化 导航控制器栈的push和pop跳转理解

    (1)导航控制器初始化的时候一般都有一个根视图控制器,导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最下面,最后进去的在最上面.在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界 ...

  6. 【iOS开发-21】UINavigationController导航控制器初始化,导航控制器栈的push和pop跳转理解

    (1)导航控制器初始化的时候一般都有一个根视图控制器,导航控制器相当于一个栈,里面装的是视图控制器,最先进去的在最以下,最后进去的在最上面.在最上面的那个视图控制器的视图就是这个导航控制器对外展示的界 ...

  7. 导航控制器生产,push,pop,root,index

    AppDelegate.m #import "FirstViewController.h" @implementation AppDelegate - (BOOL)applicat ...

  8. 导航控制器 UI_08(上)

    主要内容:UINavigationController 重要:属性传值(向后一个界面传值).代理传值(向前相邻的界面传值).单例传值(不相邻的界面向前传值) 1.UINavigationControl ...

  9. iOS彩票项目--第一天,自定义TabBar控制器和自定义TabBar,自定义导航控制器

    一.环境配置,和项目层次搭建 二.自定义TabBar 项目中TabBar中的导航按钮美工给的图片太大,图片中包含了图片和文字.最主要的是TabBar上面的按钮图片尺寸是有规定的,当高度大于44的时候, ...

随机推荐

  1. Web浏览器兼容性测试工具如何选择

    对于前端开发工程师来说,网页兼容性测试工程师而言,确保代码在各种主流浏览器的各个版本中都能正常工作是件很费时的事情,幸运的是,有很多优秀的工具可以帮助测试浏览器的兼容性,领测软件测试网向您推荐12款很 ...

  2. 分析NGINX 健康检查和负载均衡机制

    nginx 是优秀的反向代理服务器,这里主要讲它的健康检查和负载均衡机制,以及这种机制带来的问题.所谓健康检查,就是当后端出现问题(具体什么叫出现问题,依赖于具体实现,各个实现定义不一样),不再往这个 ...

  3. Nginx之RTMP

    1. RTMP协议介绍 RTMP(Real Time Messaging Protocol)实时消息传送协议是Adobe Systems公司为Flash播放器和服务器之间音频.视频和数据传输开发的私有 ...

  4. Canvas translate- 平移

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 国内值得关注的官方API集合

    项目地址:https://github.com/marktony/Awesome_API 本页仅收集国内部分官方API,如需查看其他版本,请点击这里. 目录 笔记 出行 词典 电商 地图 电影 后端云 ...

  6. Bootstrap入门(十三)组件7:导航条

    Bootstrap入门(十三)组件7:导航条 1.默认样式的导航条 2.嵌入表单和按钮 3.嵌入文本和非导航的链接 4.组件排列和下拉菜单 5.固定在顶部/底部 6.反色的导航条 7.路径导航 首先先 ...

  7. CodeForces 721B

    B. Passwords time limit per test:2 seconds memory limit per test:256 megabytes input:standard input ...

  8. 玩转spring boot——结合阿里云持续交付

    前言 在互联网项目中,项目测试.部署往往需要花费大量时间.传统方式是在本地打包.测试完毕程序,然后通过ftp上传至服务器,再把测试的配置文件修改为生产环境的配置文件,最后重新运行服务.这一过程如果交给 ...

  9. 【G】开源的分布式部署解决方案 - 预告篇

    为什么想到要做分布式部署解决方案? 当项目越做越大以后,你会发现部署变成一件极其头疼的事情.当然头疼的绝不仅仅在部署一个环节,比如新服务器环境搭建当中就许多坑要踩.各种重复性的工作,包括但不仅限于增加 ...

  10. 你需要了解的 Core Spotlight

    你需要了解的 Core Spotlight -- 了解Spotlight Core Spotlight是iOS 9中苹果推出了新的Search API,可以直接搜App内的内容(in-App Sear ...