思路
首先你总要知道interactivePopGestureRecognizer,这是导航控制器的一个边界滑动返回手势,我们说轻松,其实就是基于这个手势来做的,通过打印可以看到它是一个Pan手势,所以我们的思路就是在自定义导航控制器中创建一个UIPanGestureRecognizer,把Target跟Action都设置成interactivePopGestureRecognizer的Target跟Action,这样就可以通过我们的Pan手势来做interactivePopGestureRecognizer所做的事情了😀。

interactivePopGestureRecognizer
问题
如何获取interactivePopGestureRecognizer的Target跟Action ?
从打印可以看出,action=handleNavigationTransition:,所以Action可以直接通过@selector()来取,而Target其实就是手势的代理,我们也来打印验证一下
NSLog(@"delegate==%@",self.interactivePopGestureRecognizer.delegate);

Target
显然Target就是手势代理。
步骤
- 创建导航控制器基类,只要有需要添加全屏滑动返回的,继承它就好。
- 创建
UIPanGestureRecognizer指向interactivePopGestureRecognizer的Target跟Action。 - Pan手势代理中添加相关判断约束。
代码
- (void)addFullScreenPopPanGesture{
self.fullScreenPopPanGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
self.fullScreenPopPanGesture.delegate = self;
[self.view addGestureRecognizer:self.fullScreenPopPanGesture];
[self.interactivePopGestureRecognizer requireGestureRecognizerToFail:self.fullScreenPopPanGesture];
self.interactivePopGestureRecognizer.enabled = NO;
}
#pragma mark -- UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer isEqual:self.fullScreenPopPanGesture]) {
//获取手指移动后的相对偏移量
CGPoint translationPoint = [self.fullScreenPopPanGesture translationInView:self.view];
//向右滑动 && 不是跟视图控制器
if (translationPoint.x > 0 && self.childViewControllers.count > 1) {
return YES;
}
return NO;
}
return YES;
}

效果
注意
- API是iOS7以后的,所以低于iOS7的就自然不能如此了。
-
必须将自带的
interactivePopGestureRecognizer关闭,以及两者共存时自带的手势失效,以防在其他地方又开启,导致冲突。 - 需要在代理中判断是往右滑且不是根控制器才生效,避免跟其他手势冲突。