-
设想:
- 为什么当push进去的控制器,会有滑动功能。
- 是不是系统调用了,某个对象的某个方法。
- 是不是自己给控制器的view加个滑动手势pan,然后去实现那个对象的那个方法,就能实现全屏滑动呢。
-
实现
- 添加手势,很容易。但是怎么得到
对象和方法
。 - 我们有
self.interactivePopGestureRecognizer
从这里入手,来取得对象和方法
. - 打印可以直接获得方法
- 系统的滑动手势触发的时候,会调用Target的action,去做滑动返回的事情(action),
- 获取系统滑动返回的target和action
- action:=> handleNavigationTransition:
- 可以通过
运行机制
来得到变量名 - 添加头文件
#import <objc/runtime.h>
- 获取成员变量,知道属性名,
- 怎么通过运行时机制获取属性值,首先得要获取属性的名,通过KVC获取值 (系统内部非开源属性,只能用KVC获取,修改)
- 获取target,需要使用运行时机制,遍历出类里面所有属性名
- 利用运行时获取属性名,只能获取当前类下的所有属性名,并不能获取它的子类或者父类。
- 添加手势,很容易。但是怎么得到
- (viod)viewDidLoad
{
unsigned int count = 0;
// 获取UIGestureRecognizer里所有的成员属性
Ivar *ivars = class_copyIvarList([UIGestureRecognizer class], &count);
for (int i = 0; i < count; i++) {
// 获取成员属性
Ivar ivar = ivars[i];
// 获取成员属性的属性名
NSString *name = @(ivar_getName(ivar));
// NSLog(@"%@",name);
// 取得属性中的对象
NSArray *targets = [gesture valueForKeyPath:@"_targets"];
id gestureRecognizer = targets[0];
// 去得其_target,属性值
id target = [gestureRecognizer valueForKeyPath:@"_target"];
//
// NSLog(@"%@",target);
self.interactivePopGestureRecognizer.enabled = NO;
// 借用系统的滑动手势的功能,当触发自己的滑动手势的时候,调用系统的滑动返回功能
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)];
pan.delegate = self;
[self.view addGestureRecognizer:pan];
}
- copyIvarList:获取成员属性列表
- Class:获取哪个类下面的属性
- outCount:这个类有多少个成员属性,成员属性的总数
- 注意,如果是根控制器的话,则不需要进行滑动,不触发手势。代码实现
// 如果返回no,表示不触发这个手势
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
// 只有非跟控制器才能拥有滑动返回功能 子控件数为1,因为根控制器也为其子控制器。所以为1时,就是只子控制器。
return self.childViewControllers.count != 1;
}