iOS(Swift)-Runtime之关于页面跳转的捷径【Runtime获取当前ViewController,很常用】
写在前面
在我们操作页面跳转时,如果当前的类不是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,很常用】的更多相关文章
- iOS-Runtime之关于页面跳转的捷径【Runtime获取当前ViewController】
写在前面 在我们操作页面跳转时,如果当前的类不是UIViewcontroller(下面用VC表示),你会不会写一个代理,或者block给VC传递信息,然后在VC里面进行 ///假如targetVc是将 ...
- react项目中页面跳转、刷新及获取网络状态
// 页面跳转 window.location.href = 'http://speedtest.wangxiaotong.com/' // 页面刷新 window.location.reload() ...
- swift 下storyboard的页面跳转和传值
------------------1. 最简单的方法 拖拽, 这个就不用多解释了吧. 直接拖拽到另一个视图控制器, 选择 show, 就行了. 2. 利用 Segue 方法 (这里主要是 方法1 的 ...
- mui 每次页面跳转用mui.openWindow会不会占用很大内存?
http://ask.dcloud.net.cn/question/5384 不能每次用mui.openWindow.不用的webview要close,一个webview被close后会露出其他没有被 ...
- vue页面跳转以及传参和取参
vue中this.$router.push()路由传值和获取的两种常见方法 1.路由传值 this.$router.push() (1) 想要导航到不同的URL,使用router.push()方法 ...
- iOS——使用StroryBoard页面跳转及传值
之前在网上搜iOS的页面跳转大多都是按回以前的那种xib的形式,但鄙人是使用storyboard的.这篇就只介绍利用storyboard进行页面跳转与传值. 新建页面 iOS的程序也是使用了MVC的思 ...
- phonegap + 推送 + 页面跳转 (ios)
os如果没有页面跳转的需求的话就使用极光推送,如果有页面跳转如果用了极光推送就只有用oc去写,但是我不会oc,所以智能放弃极光选用ios自己的apns来实现 新建项目跟安卓创建项目差不多,新建完成后就 ...
- ios&h5混合开发项目仿app页面跳转优化
前言:本人原本是ios开发工程师,但由于现今H5的兴起,行内刮起了一阵混合开发的风气,趁着这股劲,我也学了前端开发,不说研究的多深,但也能胜任日常的开发工作.长话短说,现今的混合开发应该还处于摸索阶段 ...
- ios学习-delegate、传值、跳转页面
ios学习-delegate.传值.跳转页面 1.打开xcode,然后选择ios--Application--Empty Application一个空项目. 项目目录: 2.输入项目名称以及选 ...
随机推荐
- 2018.08.19 NOIP模拟 dp(二分+状压dp)
Dp 题目背景 SOURCE:NOIP2015-SHY-10 题目描述 一块土地有 n 个连续的部分,用 H[1],H[2],-,H[n] 表示每个部分的最初高度.有 n 种泥土可用,他们都能覆盖连续 ...
- arduino 中通过寄存器地址访问寄存器内容
void call_func( void (*func)(void)){ (*func)(); } void setup() { // put your setup code here, to run ...
- htoi的实现
htoi的实现 /************************************************************************* > File Name: h ...
- 初探Java反射机制
反射库提供了一个非常丰富且精心设计的工具集,以便编写能够动态操纵java代码的程序库.这项功能被大量地应用于JavaBeans中.反射机制提供了在运行状态中获得和调用修改任何一个类的属性和方法的能力. ...
- Go并发编程基础(译)
2015-05-20 三 By youngsterxyf 原文:Fundamentals of concurrent programming 译者:youngsterxyf 本文是一篇并发编程方面的入 ...
- SpringMvc中controller之间的方法调用
方法一, return new ModelAndView("redirect:"+新地址); 方法二, response.sendRedirect(新地址); return nul ...
- D3 drag
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Useful Field of View (UFOV)
IE8不支持canvas,使用excanvas.js,js代码需要放在window.onload=function(){...}内,$(docuemnt).ready(function(){...}) ...
- 团队项目第六周——事后诸葛亮分析(GG队)
一.总结: 本次项目作为我们第一次团队集体开发的项目,使我们在项目开发以及团队合作方面都有了宝贵的 经验以及初步的认识: 从项目开发的方面来看: 通过本次项目,我们更进一步加强了自己的前端知识,并初步 ...
- Oracle EBS中有关Form的触发器的执行顺序
http://blog.csdn.net/postfxj/article/details/8135769 触发器执行顺序: 1. 当打开FORM时: (1) PRE-FORM (2) ...