最近在做项目的就遇到了这个问题,UIScrollView横向滑动和返回手势冲突.要想知道怎么解决问题,我们最好先要知道为什么会有这样的问题.普及一下知识:iOS系统中,滑动返回手势,其实是一个UIPanGestureRecognizer,系统默认的操作是只有滑动屏幕的左边的某个位置,UIPanGestureRecognizer才会起作用。UIScrollView的滑动手势也是UIPanGestureRecognizer。UIGestureRecognizer和UIView是多对一的关系,UIGestureRecognizer一定要和view进行绑定才能发挥作用。因此不难想象,UIGestureRecognizer对于屏幕上的手势事件,其接收顺序和UIView的层次结构是一致的
UINavigationController.view —> UIViewController.view —> UIScrollView —> Screen and User's finger
即UIScrollView的panGestureRecognizer先接收到了手势事件,直接就地处理而没有往下传递。
实际上这就是两个panGestureRecognizer共存的问题。
好了,知道了问题,相信它也就没那么难解决了~~~
方式1
查到的资料中这用方法使用的次数是最多的,而且也是最简单的,应该是为不少人解决了这个冲突的难题,但是不知道为什么用到我的项目是是没有用的,因此我才找了不知一种方法.代码如下
[_ZJJLScrollView.panGestureRecognizer requireGestureRecognizerToFail:self.navigationController.interactivePopGestureRecognizer];
其实这个方法不止是适用于scrollView返回冲突,而且也同样适用于tableView,因为表视图是继承自滚动视图的.
方式2
1.首先自定义一个scrollView,比如:CustomScrollView,遵守<UIGestureRecognizerDelegate>协议,然后在实现文件中写如下代码:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
// 首先判断otherGestureRecognizer是不是系统pop手势
if ([otherGestureRecognizer.view isKindOfClass:NSClassFromString(@"UILayoutContainerView")]) {
// 再判断系统手势的state是began还是fail,同时判断scrollView的位置是不是正好在最左边
if (otherGestureRecognizer.state == UIGestureRecognizerStateBegan && self.contentOffset.x == 0) {
return YES;
}
}
return NO;
}
2.那个横向滚动的scrollView继承这个自定义scrollView,也就是CustomScrollView
原理:scrollView的pan手势会让系统的pan手势失效,所以我们只需要在系统手势失效且scrollView的位置在初始位置的时候让两个手势同时启用就可以了
写的这里,上述问题就已经解决了,但是在这里我又联想到了之前遇到的一个已经解决的问题,当整个界面铺满了webView的时候,有时候也会出现无法返回的问题,该怎么解决呢?来,看代码:
// 允许多个手势并发
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
在控制器敲上上述的方法就可以了,是不是很简单?