在处理 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. 查看AIX是32位还是64位,查看内存、cpu等参数

    prtconf 64位也可以查看: ls -l /unix

  2. Android系列一、创建项目

    本文是在MAC下的Android Studio操作的. 一.Android入门 1.打开Android Studio,界面如下: 几个选项的意思: 创建一个新的项目 打开一个已经存在的项目 从版本管理 ...

  3. I/O模型浅析

    引入 首先来说一下进程: 进程在就是一段执行中的代码,他是由一条条指令和数据组成的一个具有生命周期的有头有尾的实体. 进程根据权限大体上可以分为两类:用户进程 和 内核进程. 这两者的主要区别在于权限 ...

  4. libMF阅读记录(一):首先要编译通过

    libMF是林智仁老师开发的一个用于推荐系统的矩阵分解库,下载地址:libMF 测试用的数据集是MovieLen,一个给电影评分的数据集,下载在此:ML 最近在阅读libMF的源代码,并且准备开发其M ...

  5. 《Effective Objective-C 2.0》 读后总结

    感觉自己最近提升很慢了.然后去找了一些面试题看看.发现自己自大了.在实际开发中,让我解决bug.编写功能,我有自信可以完成.但是对项目更深层的思考,我却没有.为了能进到自己的目标BAT.也为了让自己更 ...

  6. MVC中登录页图片验证码总结

    直接上代码了 using System;using System.Collections.Generic;using System.Drawing;using System.Drawing.Imagi ...

  7. MySQL日志系统

    body { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-top: 10 ...

  8. 关于C# XmlDocument方法Load加载流后自动释放流的解决方法

    在实际应用doc.Load(Request.InputStream)的时候,doc.Load方法内置默认释放流 造成再次度Request.InputStream的时候,代码报错 替换方法: XmlDo ...

  9. jquery序列化form表单

    在开发中有时需要在js中提交form表单数据,就需要将form表单进行序列化. jquery提供的serialize方法能够实现. $("#searchForm").seriali ...

  10. 如何把函数都用promise方式实现?

    如何把函数都用promise方式实现? 我觉得这是一个好问题.当前在我所在的公司,只要用 NodeJS 进行开发,从框架到具体的应用实例到工具,已经全部迁移到以 promise 为中心开发方式.带来的 ...