写在前面

在我们操作页面跳转时,如果当前的类不是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. Codeforces-8VC Venture Cup 2016-Elimination Round-626A.暴力 626B.水题 626C.二分

    A. Robot Sequence time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  2. 二维字符数组利用gets输入

    char a[10][81];for(int i=0;i<10;i++)gets(a[i]); a是二维数组的数组名,相当于一维数组的指针,所以a[i]就相当于指向第i个数组的指针,类型就相当于 ...

  3. Replacement(思维题)

    题目链接:http://codeforces.com/problemset/problem/570/C C. Replacement time limit per test 2 seconds mem ...

  4. 【CC2530入门教程-增强版】基础技能综合实训案例(基础版)-上位机源码

    [CC2530入门教程-增强版]基础技能综合实训案例(基础版)-上位机源码 广东职业技术学院  欧浩源 一.需求分析 按照指定参数打开串口,与测控终端建立数据传输通道,并根据应用要求实现程序逻辑,具体 ...

  5. insertBefore方法(javascript与jQuery)

    说到insertBefore()方法,其实javascript与jQuery中都有此方法,那么他们用法是否相同呢? 其实,还是有点区别的.反正我是爱搞混淆了,先做个小笔记吧! 1.insertBefo ...

  6. Redis Cluster集群搭建与应用

    1.redis-cluster设计 Redis集群搭建的方式有多种,例如使用zookeeper,但从redis 3.0之后版本支持redis-cluster集群,redis-cluster采用无中心结 ...

  7. surging 微服务框架使用系列之surging介绍

    首先,感谢surging的作者fanliang11为.net开源做出的贡献 其次, surging 的git地址:https://github.com/dotnetcore/surging surgi ...

  8. git常见操作

    本地仓库关联远程仓库 新建本地目录scala git init 这样就新建了一个本地仓库 在远端如github上新建仓库scala 关联远程仓库 git remote add origin git@g ...

  9. PHP开发api接口安全验证

    php的api接口 在实际工作中,使用PHP写api接口是经常做的,PHP写好接口后,前台就可以通过链接获取接口提供的数据,而返回的数据一般分为两种情况,xml和json,在这个过程中,服务器并不知道 ...

  10. windows下如何创建没有名字的.htaccess文件

    http://www.mdaima.com/jingyan/35.html WINDOWS下建立空名的.htaccess文件 ? 大家都知道,在windows环境下是不能直接建立没有名字的文件的,那我 ...