- 继凌晨的那一篇实现在自定义导航栏返回按钮的情况下实现和系统自带的滑动返回效果文章后,继续完成全屏返回的效果
- 实现这个功能的方法有很多,网上也有很多类似的文章,各位大牛也都写的很不错,我看了有的是push之后生成一张图片然后返回的时候使用的,也有和我今天要说的让系统帮我们完成这个操作类似的,但是我感觉还是有必要说上那么一说说的~~~
实现该功能前我们需要思考的问题
1)系统自带的滑动返回功能已经默认实现了,那么我们能不能直接把系统的这个返回功能拿过来为我们所用呢?
2)这个功能属于手势的一个功能,平时我们自己定义手势需要通过给手势进行设置一个target,在手势改变的时候进行相应的action处理,那么系统内部是否也是通过这样实现的呢?
-
携带以上问题,通过断点调试发现了几个东东
系统滑动手势类型:UIScreenEdgePanGestureRecognizer 这个滑动手势的target:_UINavigationInteractiveTransition 触发这个手势的时候的action:handleNavigationTransition:
说白了就是_UINavigationInteractiveTransition监听了UIScreenEdgePanGestureRecognizer的触发情况,触发的话调用自己的handleNavigationTransition:方法
目前研究出来了2个办法都可以实现这个全屏滑动 -
第一种情况
根据上述断点打印情况,那么我们接下来需要处理的就是如何去拿到这个target(_UINavigationInteractiveTransition) -
它是系统内部的东东,想要拿到它我们需要使用到
- KVC (前提条件:必须知道属性名)
- 运行时
-
具体怎么拿到这个 target的,出于这个功能的简单化,这里就不赘述了,因为后续我们想要实现这个功能,只需要知道这个属性名就可以了,大可以不必考虑怎么去拿到它
-
第二种情况
-
其实target = self.interactivePopGestureRecognizer.delegate
-
哈哈,那这样就更简单了,直接将target替换就可以啦
-
ok,忙活了这么久,下面直接上实现了,也是很简单的
1)和2)2个步骤在viewDidLoad 方法完成即可
1)// 防止手势冲突,先把系统的手势给关闭了,用我们自己的
self.interactivePopGestureRecognizer.enabled = NO;
2)// 取出系统手势的target对象,前提是我们已经知道了它的名字就是@“_targets”
NSArray *targets = [self.interactivePopGestureRecognizer valueForKeyPath:@"_targets"];
id objc = [targets firstObject];
id target = [objc valueForKeyPath:@"_target"];
//我们自己创建一个手势,
//情况一
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget: target action:@selector(handleNavigationTransition:)];
//情况二
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
//让导航控制器成为我们自定义手势的代理,实现下面的代理方法
//这个时候需要让当前控制器遵守<UIGestureRecognizerDelegate>
pan.delegate = self;
//添加手势
[self.view addGestureRecognizer:pan];
#pragma mark - 手势代理方法
// 是否开始触发手势
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
// 判断当前控制器是否是根控制器,是的话不要触发手势
return (self.topViewController != [self.viewControllers firstObject]);
}
网友评论