写在前面

在我们操作页面跳转时,如果当前的类不是UIViewcontroller(下面用VC表示),你会不会写一个代理,或者block给VC传递信息,然后在VC里面进行

 ///假如targetVc是将要跳转的页面
[self.navigationController pushViewController:targetVc animated:YES];

拿tableViewCell做例子,如果每个页面展示的tableViewCell中,如果存在不少的这样操作,就会写很多代理或者block,如果不这样,那又该怎么做呢,思路是获取当前显示在最顶层的VC,网上有很多方法,先看一个普通的方法

- (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;
}

上面的方法可以或许可以获取最顶层的VC(我在网上找的一个,没有测试,这里只做对比),但是有没有感觉很繁琐,当然也可以把它写在一个工具里面,每次用这个工具里面的这个方法,也可以获取,但是我始终觉得繁琐,哈哈;

利用Runtime实现

runtime是一个好玩的东西,上一篇我简单说了它的一些常用功能,这里结合Category来实现获取当前VC需求

1.新建一个基于UIApplication的分类

点击下一步就建好了

2.利用Runtime添加属性

在UIApplication+CurrentViewController.h文件中,添加

///用于获取当前 UIViewController
@property (nonatomic, weak) UIViewController *currentViewController;

在UIApplication+CurrentViewController.m文件中,引入头文件

#import <objc/runtime.h>

利用runtime实现属性的get set方法

///set
- (void)setCurrentViewController:(UIViewController *)currentViewController{
objc_setAssociatedObject(self, @selector(currentViewController), currentViewController, OBJC_ASSOCIATION_ASSIGN);
}
///get
- (UIViewController *)currentViewController{
return objc_getAssociatedObject(self, _cmd);
}

3.实现

在需要获取当前VC的文件中,引入头文件,也可以直接将该头文件放入宏文件中

#import "UIApplication+CurrentViewController.h"

在VC的viewWillAppear方法中,添加

[UIApplication sharedApplication].currentViewController = self;

这样,我们在任何一个地方获取,只需要添加如下代码,就可以获取当前的VC,获取到之后,不管是push、present还是performSegueWithIdentifier,都可以实现页面的跳转

UIViewController *viewVc = [UIApplication sharedApplication].currentViewController;

4.延伸

上面在需要用到的在每一个VC中都需要添加

[UIApplication sharedApplication].currentViewController = self;

那么,可以建一个基于UIViewController的基类BaseViewController,然后在BaseViewController的viewWillAppear方法中添加上述代码,我们在新建VC时,只需要继承BaseViewController就可以了!

*****************Swift实现*****************

extension UIApplication {
struct RuntimecurrVcKey {
static let currVcKey = UnsafeRawPointer.init(bitPattern: "currVcKey".hashValue)
} var currViewController: UIViewController? {
get {
return objc_getAssociatedObject(self, UIApplication.RuntimecurrVcKey.currVcKey!) as? UIViewController
}
set(newValue) {
objc_setAssociatedObject(self, UIApplication.RuntimecurrVcKey.currVcKey!, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
}
}

iOS-Runtime之关于页面跳转的捷径【Runtime获取当前ViewController】的更多相关文章

  1. iOS(Swift)-Runtime之关于页面跳转的捷径【Runtime获取当前ViewController,很常用】

    写在前面 在我们操作页面跳转时,如果当前的类不是UIViewcontroller(下面用VC表示),你会不会写一个代理,或者block给VC传递信息,然后在VC里面进行 ///假如targetVc是将 ...

  2. ios基础之 透过页面跳转来认识 Strong 与 Weak

    最近在自己做一个小程序,遇到了页面跳转的问题,然后上网一通乱搜,跳转的问题解决了,又有传值的问题.上面两个问题解决了,又发现内存比刚开始时多占用了2M,于是,各种内心纠结,想彻底 搞清楚strong ...

  3. react项目中页面跳转、刷新及获取网络状态

    // 页面跳转 window.location.href = 'http://speedtest.wangxiaotong.com/' // 页面刷新 window.location.reload() ...

  4. iOS推送后页面跳转

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launc ...

  5. vue页面跳转以及传参和取参

    vue中this.$router.push()路由传值和获取的两种常见方法 1.路由传值   this.$router.push() (1) 想要导航到不同的URL,使用router.push()方法 ...

  6. JS判断是否是微信页面,判断手机操作系统(ios或android)并跳转到不同下载页面

    JS判断客户端是否是iOS或者Android 参考:http://caibaojian.com/browser-ios-or-android.html function is_weixin() { v ...

  7. iOS——使用StroryBoard页面跳转及传值

    之前在网上搜iOS的页面跳转大多都是按回以前的那种xib的形式,但鄙人是使用storyboard的.这篇就只介绍利用storyboard进行页面跳转与传值. 新建页面 iOS的程序也是使用了MVC的思 ...

  8. phonegap + 推送 + 页面跳转 (ios)

    os如果没有页面跳转的需求的话就使用极光推送,如果有页面跳转如果用了极光推送就只有用oc去写,但是我不会oc,所以智能放弃极光选用ios自己的apns来实现 新建项目跟安卓创建项目差不多,新建完成后就 ...

  9. ios&h5混合开发项目仿app页面跳转优化

    前言:本人原本是ios开发工程师,但由于现今H5的兴起,行内刮起了一阵混合开发的风气,趁着这股劲,我也学了前端开发,不说研究的多深,但也能胜任日常的开发工作.长话短说,现今的混合开发应该还处于摸索阶段 ...

随机推荐

  1. struts2(三)之表单参数自动封装与参数类型自动转换

    前言 对struts2的使用不外乎这几点,参数自动封装,拦截器的使用,数据校验,ognl表达(值栈和actionContext的讲解),struts2的标签,struts2的国际化, struts2的 ...

  2. hihoCoder #1043 : 完全背包(板子题)

    #1043 : 完全背包 时间限制:20000ms 单点时限:1000ms 内存限制:256MB 描述 且说之前的故事里,小Hi和小Ho费劲心思终于拿到了茫茫多的奖券!而现在,终于到了小Ho领取奖励的 ...

  3. 1022: [SHOI2008]小约翰的游戏John【Nim博弈,新生必做的水题】

    1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2709  Solved: 1726[Submit] ...

  4. linux 操作系统/xxx目录下都是什么文件?

    /bin:存放最常用命令: /dev:设备文件: /etc:存放各种配置文件: /home:用户主目录: /lib:系统最基本的动态链接共享库: /mnt:一般是空的,用来临时挂载别的文件系统: /b ...

  5. MongoDb在windows下的安装与以auth方式启用服务

    一.下载安装 1.去官网上下载适合自己电脑的MongoDB版本  下载MongoDB 2.安装MongoDB 安装还是比较简单,按照步骤一步一步往下走就可以了. 3.启动MongodDB 安装完成之后 ...

  6. CentOS 6.5 编译安装 LNMP环境

    建立一个软件包目录存放 mkdir -p /usr/local/src/ 清理已经安装包 rpm -e httpd rpm -e mysql rpm -e php yum -y remove http ...

  7. 常用Windows DOS命令项目部署经常用到

    img { max-width: 100% } 前两天部署.netcore项目,首先是生产环境域名访问不了,再到.netcore项目IIS部署502.5,在到莫名其妙的500,在排查项目部署问题的时候 ...

  8. c#委托事件入门--第二讲:事件入门

    上文 c#委托事件入门--第一讲:委托入门 中和大家介绍了委托,学习委托必不可少的就要说下事件.以下思明仍然从事件是什么.为什么用事件.怎么实现事件和总结介绍一下事件 1.事件是什么:. 1.1 NE ...

  9. webpack运行常见错误归纳

    今天在运行项目的时候,又遇到坑了,在公司运行的好好的项目,到我自己电脑上就报错,提示跨域,想了好久都不明白为啥,webpack配置文件里的ip地址我也改成与本地ip对应的,百思不得其解,在寻求别人帮助 ...

  10. 算法-java代码实现堆排序

    堆排序 第7节 堆排序练习题 对于一个int数组,请编写一个堆排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3],6 [1,2 ...