写在前面

在我们操作页面跳转时,如果当前的类不是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(Swift)-Runtime之关于页面跳转的捷径【Runtime获取当前ViewController,很常用】的更多相关文章

  1. iOS-Runtime之关于页面跳转的捷径【Runtime获取当前ViewController】

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

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

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

  3. swift 下storyboard的页面跳转和传值

    ------------------1. 最简单的方法 拖拽, 这个就不用多解释了吧. 直接拖拽到另一个视图控制器, 选择 show, 就行了. 2. 利用 Segue 方法 (这里主要是 方法1 的 ...

  4. mui 每次页面跳转用mui.openWindow会不会占用很大内存?

    http://ask.dcloud.net.cn/question/5384 不能每次用mui.openWindow.不用的webview要close,一个webview被close后会露出其他没有被 ...

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

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

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

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

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

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

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

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

  9. ios学习-delegate、传值、跳转页面

    ios学习-delegate.传值.跳转页面     1.打开xcode,然后选择ios--Application--Empty Application一个空项目. 项目目录: 2.输入项目名称以及选 ...

随机推荐

  1. sublime3中运行python 和设置

    点bulid system建立下面文件 {"cmd":["C:/ProgramData/Anaconda3/python.exe", "-u" ...

  2. windown 安装配置 mvn不是内部或外部命令

    path 检查没有任何问题,就直接把maven路径直接放到path前面 如果提示JAVA_HOME not found 之类错误,环境变量中需要设置JAVA_HOME,而且需要在path中添加%JAV ...

  3. Unsorted, maximum ==> sorted

    https://github.com/Premiumlab/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/Moc ...

  4. Jfinal框架是什么框架?适用于什么项目呢?

    Jfinal框架是什么框架?适用于什么项目呢? jfinal 基于spring MVC研发的框架,操作简单.节省代码,适用于所有web项目.适合中小型项目开发.10分钟写出一个页面的增删改查.目前所在 ...

  5. 2018.10.15 loj#6013. 「网络流 24 题」负载平衡(费用流)

    传送门 费用流sb题. 直接从sss向每个点连边,容量为现有物品量. 然后从ttt向每个点连边,容量为最后库存量. 由于两个点之间可以互相任意运送物品,因此相邻的直接连infinfinf的边就行了. ...

  6. 2018.09.30 bzoj4025: 二分图(线段树分治+并查集)

    传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...

  7. HDU 4562 守护雅典娜 (计算几何+DP)

    守护雅典娜 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submi ...

  8. hdu 4972 根据每轮篮球赛分差求结果

    http://acm.hdu.edu.cn/showproblem.php?pid=4972 两支球队进行篮球比赛,每进一次球后更新比分牌,比分牌的计数方法是记录两队比分差的绝对值,每次进球的分可能是 ...

  9. 16、Docker的网络-host和none

    16.1 none   创建一个容器使用网络none: [root@docker ~]# docker run -d --name test1 --network none busybox /bin/ ...

  10. [label][翻译][JavaScript Regular Expression]JavaScript Regular Expressions

    原文:http://www.javascriptkit.com/javatutors/re.shtml 校验用户的输入是每一个软件开发者的必须要做的事情. 正则表达式与模式 如何在JavaScript ...