iOS - APP任意push新页面那些事
大家都知道,UINavigationController对象有一个方法pushViewController,用来做视图跳转,也是在iOS开发中常用的页面转换方法之一。大多数APP的结构一般都是,使用一个UITabBarController,每个tab上都是一个UINavigationController,然后各个tab上的navigationController自己管理各自的视图栈。

这个时候,如果此时APP想要push一个新的VC,一般是在某个VC上调用:
[self.navigationController pushViewController:newVC animated:YES];
那问题来了,产品比较任性,如果有一个需求,就是要求做一个跳转工具,要求要能在任何地方(包括非VC中),都能在当前页面push新的VC,那又该怎么做呢?

如果能拿到UITabBarController的对象,例如放在了delegate中(这里设想AppDelegateInstance就是delegate的对象,而UITabBarController的成员变量名为tabBar),也可以使用
[AppDelegateInstance.tabBar.selectedViewController pushViewController:newVC animated:YES];
好像能随时push新VC了......
不对!状况又来了,如果在当前VC上可能又present出一个页面,即present出一个新的NAV,这时候:

这个时候,有可能AppDelegateInstance.tabBar.selectedViewController就不是当前的NAV了,自然就不能正确push了。
那怎么办呢?

如果能拿到当前正在显示的NAV就好办多了,那样我直接拿这个NAV就可以push任何页面了。
思路:
1.当前显示的肯定有一个window包含了所有视图控制器、导航控制器;
2.视图控制器、导航控制器出现的方式只有3中:tabBar selected、push、present;
3.从“1”的window出发,找到每一层显示中的NAV或者VC,直到找到最后一层,就是当前显示的VC,就能拿到当前的NAV了。
这里我创建了一个分类UIApplication+Visible,获取APP的主window,再递归进行当前显示中VC、NAV的查询:
#import "UIApplication+Visible.h"@implementation UIApplication (Visible)- (UIWindow *)mainWindow {return self.delegate.window;
}- (UIViewController *)visibleViewController {UIViewController *rootViewController = [self.mainWindow rootViewController];return [self getVisibleViewControllerFrom:rootViewController];
}- (UIViewController *) getVisibleViewControllerFrom:(UIViewController *) vc {if ([vc isKindOfClass:[UINavigationController class]]) {return [self getVisibleViewControllerFrom:[((UINavigationController *) vc) visibleViewController]];} else if ([vc isKindOfClass:[UITabBarController class]]) {return [self getVisibleViewControllerFrom:[((UITabBarController *) vc) selectedViewController]];} else {if (vc.presentedViewController) {return [self getVisibleViewControllerFrom:vc.presentedViewController];} else {return vc;}}}- (UINavigationController *)visibleNavigationController {return [[self visibleViewController] navigationController];
}
@end
然后你就这样调用
UINavigationController *nav = [[UIApplication sharedApplication] visibleNavigationController];
[nav pushViewController:newVC animated:YES];
成功啦!!!

最后,可能有些人要疑惑,为什么mainWindow方法中要使用delegate.window而不使用[UIApplication sharedApplication].keyWindow呢?
因为keyWindow并不是一直都是APP的主界面的window,例如使用了UIAlertView,keyWindow就会变成alertView的window,这时候我们的轮子就不能跑了。
好了,可能有些地方写得比较模糊、或者有缺陷,欢迎指出。
相关文章:

主攻ASP.NET.4.5 MVC4.0之重生:Entity Framework生成实体类步骤(十三)
1.新建一个ASP.NET MVC 4.0 项目 2.安装Entity Framework Power Tools 3.Entity Framework- -RepositoryReverse Engineer Code First 4.Install-Package EntityFramework or Update-Package EntityFramework PM -Repository Install-Package EntityFramework 已安装“EntityFr…

【廖雪峰Python学习笔记】高阶函数
Higher-order function高阶函数映射过滤算法排序算法高阶函数 变量可指向函数 >>> abs # 函数 <built-in function abs> >>> abs(-0) # 函数调用 0 >>> func abs # 变量可指向函数 >>> func(-9) # 调用变量 调用函数 9函数名…

丁贵才130702010042第二次作业
第二次作业 2.9 设有如下语句,请用相应的谓词公式分别把它们表示出来: (1)有的人喜欢梅花,有的人喜欢菊花,有的人既喜欢梅花有喜欢梅花。 解:定义谓词 P(x):x…

SpringMVC @RequestBody接收Json对象字符串
以前,一直以为在SpringMVC环境中,RequestBody接收的是一个Json对象,一直在调试代码都没有成功,后来发现,其实 RequestBody接收的是一个Json对象的字符串,而不是一个Json对象。然而在ajax请求往往传的都是Js…

【iOS】自定义日期选择器
自定义了一个日期选择器,与大家分享一下,期待宝贵建议。 github下载地址:https://github.com/huahua0809/XHDatePicker 下面只是说明一下怎么用,具体实现请下载代码看看; 如果大家觉得这个分享有所帮助的话,…

【廖雪峰Python学习笔记】函数式编程
Functional Programming高阶函数返回函数匿名函数装饰器偏函数高阶函数 面向过程的程序设计: 把大段代码拆成函数,通过一层层函数调用,可将复杂任务分解成若干简单的任务函数是面向过程的程序设计的基本单位计算机Computer && 计算c…

asp 随机读取ID之Access
我在用ASP连接access 这个桌面数据库的时候,有时候要随机读取ID,传统的办法是: select top 3 * from tablename order by Rnd(ID) 但这样不行,默认还是按ID排序。 解决办法加上timer() 这个函数 select top 3 * from tablenam…

iOS Plist 文件的 增 删 改
一:Plist 文件的创建 Plist 文件作为我们IOS开发的一种数据存储文件,还是经常会用到的。在看《X-code江湖录》的时候,看到了这一点。自己就写了一下,把写的东西分享出来!先看看它的创建,它的创建和我们其他…
Shine Button动画效果 类似Tinder APP的卡片界面
Shine Button动画效果--WCLShineButton 类似太阳动画的button FSPagerView 主要使用UICollectionView实现的优雅的屏幕幻灯片效果,主要用于Banner、产品展示、欢迎引导等。有Swift和OC两个版本。 folding-cell 一个可扩展的具有折叠效果的内容单元格 Cell折叠动效…

【廖雪峰Python学习笔记】面向对象编程OOP
面向对象编程 OOP:Object Oriented Programming程序的基本单元:对象 [ 数据 操作数据的函数] [属性 方法]三大特点:数据封装、继承和多态OPP中的计算机程序: 一系列命令的集合 —— 一组函数顺序执行。函数化大为小࿰…
基于 CoreText 实现的高性能 UITableView
来源:伯乐在线 - Hawk0620 如有好文章投稿,请点击 → 这里了解详情 如需转载,发送「转载」二字查看说明 引起UITableView卡顿比较常见的原因有cell的层级过多、cell中有触发离屏渲染的代码(譬如:cornerRadius、maskTo…

.net程序员面试题
1. 在web页面中不论显示器的分辨率的大小是800600,还是1024768使得页面都显示在屏幕中间。 答:Margin:auto; 2. 请利用正则表达式验证一个字符串是否为数字串 (请用csharp)。 1 public static b…

Android深度探索与驱动开发(一)
Android移植可分为两个部分:应用移植和系统移植。应用移植是指将应用程序移植到某一特定硬件平台上。由于不同硬件平台之间的差异,Android SDK API也有可能存在差异,或者将应用程序从低版本Android移植到高版本的Android上。为了保证应用程序…

【廖雪峰Python学习笔记】面向对象高级编程
文章目录为实例和类绑定属性和方法\_\_slots__限制当前class实例,对子类不管用property装饰器,将getter方法变成属性多重继承 —— 一个子类可同时获得多个父类的所有功能[Mixin]定制类枚举类元类为实例和类绑定属性和方法 创建类 class Animal(object…

5分钟 搭建免费个人博客
五分钟倒数已经可以计时了。 三步完成免费个人博客搭建, 这是一篇小白也能看懂的文章,本文主要针对mac OS ,Windows 除了软件安装方式和命令有些区别(装了git bash也一样),其他基本一样。 你可能会经常看到…

基数排序之算法
一、定义基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。二、…

MyBaties学习记录
typeAliases详解: 类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余;(也就是为类型设置简称) 实例: 通过包名称加上简称调用代替; 注解表示: // …

【廖雪峰Python学习笔记】错误、调试、测试
文章目录错误处理调试单元测试unitcase文档测试错误类型程序编写问题bug – 字符类型错误等用户输入错误 – 输入不符合规定的字符串异常,程序运行时无法预测 – 磁盘满了,无法写 错误处理 错误处理机制:try…except…finally… try运行可…
iOS开发——手势识别器(用手势实现图片旋转和缩小放大)
iOS开发中,除了有关触摸的这组方法来控制用户的手指触控外,还可以用UIGestureRecognize的衍生类来进行判断,方便了开发。 UIGestureRecognize的子类类别有以下几种: UITapGestureRecognizer //轻拍识别器UIPinchGestureRecognize…
直播APP常用动画效果
作者: 落影loyinglin 地址: http://www.jianshu.com/p/a9a201ed3aa8 介绍 记录、总结开发遇到一些问题,大家一起交流学习。 这次带来,对直播APP的常用动画总结。 效果展示 下面是一个很多平台都有的入门豪华礼物动画——烟花。 一个复杂的礼物动画&…

windows8下安装Visual Studio2008
windows8下安装Visual Studio2008是一个比较麻烦的事情,不过经过我3个小时的奋斗终于安装成功了。这是我安装Visual Studio 2008过程中遇到的最复杂的一次。 下面我用图解的方式,一步一步的说明安装Visual Studio2008的过程。 第一步:因为win…

[SDK文档]SDK简介
文档链接:https://docs.growingio.com/docs/sdk-integration SDK工作方式 主要内容:GIO采集内容,数据安全措施,针对数据采集的控制项 JS SDK 添加GIO跟踪代码于<head>...</head> 之间异步加载,不影响网…

mysql主从库配置ps:mysql5.6
1 Mysql cluster版本主从服务器搭建实践 主从的作用:MySQL的主从服务器可以满足同步数据库,同步表,同步表内容,也可以指定仅同步某个数据库或某个表,还可以排除不同步某个数据库某个表。 同步原理:主从数据…

XCODE 4.5 IOS多语言设置
转:http://blog.csdn.net/samuelltk/article/details/8480403 前些天升级到Xcode4.5,现在正在用Xcode4.5IOS6开发项目,当使用国际化时,遇到了一点问题,之前版本Xcode上新建Localizable.strings后,添加语言的…
socket第三方库 AsyncSocket(源码注释解读.转)
作者 OneTea 关注 2016.09.19 11:33* 字数 0 阅读 83评论 0喜欢 1#import <Foundation/Foundation.h> class AsyncSocket;//async异步的 synchro同步 class AsyncReadPacket; class AsyncWritePacket; //extern来说可以理解为扩展吧是这样的是从一个类扩展到另一个类中的…

【每日一学】复杂度分析
文章目录目标什么是数据结构复杂度分析目标 建立时间复杂度、空间复杂度意识,写出高质量的代码能够设计基础架构提高编程技能训练逻辑思维 什么是数据结构 广义:一组数据的存储结构 | 操作数据的一种方法 解决问题:如何更快更省的处理数据…

noip2010提高组3题题解 by rLq
本题地址http://www.luogu.org/problem/show?pid1525 关押罪犯 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。他们之间的关系自然也极不和谐。很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突。我们用“怨气…

hdu 1306(字符串匹配)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid1306 思路:一开始还以为是求最长公共序列呢。。。仔细一看,orz.....就是求两个串匹配时公共部分字符最多相同的个数。。。 View Code 1 #define _CRT_SECURE_NO_WARNINGS2 #include<…

iOS之使用CoreImage进行人脸识别
更新 :应各位朋友的需求,补上了OC版本的demo, OC版下载地址 另外附上 : swift版下载地址 CoreImage是Cocoa Touch中一个强大的API,也是iOS SDK中的关键部分,不过它经常被忽视。在本篇教程中,我会带大家一起…

[HTTP协议]入门篇
文章目录http的前世今生1. 史前时期2. 创世纪3. 从产生到发展HTTP是什么与HTTP相关的各种概念与HTTP相关的技术TCP/IP协议栈http的前世今生 1. 史前时期 20世纪60年代,美国国防部高等研究计划署ARPA建立ARPA网,四个分布在各地的节点20世纪70年代&#…