使用运行时获取系统的属性:使用自己的手势修改系统自带的手势
有的时候我需要实现一个功能,但是没有想到很好的方法或者想到了方法只是那个方法实现起来太麻烦,一或者确实为了装逼,我们就会想到iOS开发中最牛逼的技术运行时(Runtime)
关于运行时这里就不多说了,请查看笔者之前搬过来了精选文章,这里主要是怎么在实际开发中使用运行时实现我们想要的功能。
比如,在iOS开发中有这样一个问题,关于导航栏中我们点击一个按钮会跳到对应的子控制器,但是这里问题就来了,我们在对应的字控制器中可以点击对应的back按钮实现返回,但是如果用户使用的是滑动的话,这里就会出问题,除什么问题呢?
问题就是:用户只能在对应的子控制器中的最左边滑动返回,音文一般我们都是实现全局界面滑动都可以的,所以这里我要解决的就是这样问题。
这里的思路是:
修改系统自带的手势滑动方法,我自己来实现,并且增加一些相应的功能。
好了下面来看看怎么使用这种牛逼的技术
一:首先我们需要导入运行时库
二:然后使用runtime的方式打印系统对应的成员属性
获取成员变量,知道属性名,
怎么通过运行时机制获取属性值,首先得要获取属性的名,通过KVC获取值
获取target,需要使用运行时机制,遍历出类里面所有属性名
利用运行时获取属性名,只能获取当前类下的所有属性名,并不能获取它的子类或者父类。
copyIvarList:获取成员属性列表
Class:获取哪个类下面的属性
outCount:这个类有多少个成员属性,成员属性的总数
1 /** 2 3 * 打印属性 4 5 */ 6 7 unsigned int count = 0; 8 9 // 获取UIGestureRecognizer里所有的成员属性 10 11 Ivar *ivars = class_copyIvarList([UIGestureRecognizer class], &count); 12 13 14 15 for (int i = 0; i < count; i++) { 16 17 // 获取成员属性 18 19 Ivar ivar = ivars[i]; 20 21 22 23 // 获取成员属性的属性名 24 25 NSString *name = @(ivar_getName(ivar)); 26 27 28 29 // NSLog(@"%@",name); 30 31 }
三:由于我们需要改变的死系统对应的手势,所以这里需要分析一下系统手势的方法和对应的属性,并且把他替换掉
- 系统的滑动手势触发的时候,会调用Target的action,去做滑动返回的事情(action),
- 获取系统滑动返回的target和action
// action:=> handleNavigationTransition:
UIScreenEdgePanGestureRecognizer *gesture = self.interactivePopGestureRecognizer;
四:从上面运行时方法打印出来的属性我们可以知道,系统对应的手势方法值是 _targets,所以我们可以使用KVC的方式改掉他。
1 NSArray *targets = [gesture valueForKeyPath:@"_targets"]; 2 3 4 5 id gestureRecognizer = targets[0]; 6 7 8 9 id target = [gestureRecognizer valueForKeyPath:@"_target"]; 10 11 12 13 // NSLog(@"%@",target); 14 15 16 17 self.interactivePopGestureRecognizer.enabled = NO; 18 19 20 21 // 借用系统的滑动手势的功能,当触发自己的滑动手势的时候,调用系统的滑动返回功能 22 23 UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)]; 24 25 26 27 pan.delegate = self; 28 29 30 31 [self.view addGestureRecognizer:pan]; 32 33