解决右滑返回手势和UIScrollView中的手势冲突

项目中遇到一个页面中是以一个scrollview横向Tab展现两个不一样功能的显示,譬如消息和公告功能,可是因为滑动返回手势和scrollview的滑动返回手势冲突了,致使页面再也不可以滑动返回。相似的还有图片浏览功能也出现过。测试

iOS系统中,滑动返回手势,实际上是一个UIPanGestureRecognizer,系统默认的操做是只有滑动屏幕的左边的某个位置,UIPanGestureRecognizer才会起做用。UIScrollView的滑动手势也是UIPanGestureRecognizer。那在侧边滑动时,让UIScrollView的不响应事件就OK了嘛,首先想到了继承UIScrollView 重写下面的方法,让滑动侧边时scrollView不响应事件,根据响应者链,事件最终会传递给下方的滑动手势。ui

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { if (point.x < location.x) { // location.x为系统的某个点的x return nil; } else { return [super hitTest:point withEvent:event]; } }

可是,这样有个问题,就是在一个页面不一样tab时,也须要滑动切换,滑动返回。spa

因为scrollView的滑动手势拦截了事件,那我重写scrollView中panGestureRecognizer的代理方法,让它不拦截就行了嘛。因而继承UIScrollView,重写下面的方法。代理

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

        if ([self panBack:gestureRecognizer]) { return YES; } return NO; } - (BOOL)panBack:(UIGestureRecognizer *)gestureRecognizer { if (gestureRecognizer == self.panGestureRecognizer) { UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer; CGPoint point = [pan translationInView:self]; UIGestureRecognizerState state = gestureRecognizer.state; if (UIGestureRecognizerStateBegan == state || UIGestureRecognizerStatePossible == state) { CGPoint location = [gestureRecognizer locationInView:self]; if (point.x > 0 && location.x < “这个本身设定" && self.contentOffset.x <= 0) { return YES; } } } return NO; }

须要侧边滑动时 panBack 返回YES,这时候,我让scrollView的手势和页面的滑动返回手势共存,scrollView不拦截手势,那不就能够滑动返回了吗。好了,测试一下,能够滑动返回,可是滑动返回时,为何scrollView也跟着在滑动呢,太影响美观了,看来还须要另外的办法,我又回到了第一种办法时的想法,让scrollView切换的时候相应panGesture,滑动返回的时候不响应,那重写scrollView中的另一个panGestureRecognizer的代理方法。code

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { if ([self panBack:gestureRecognizer]) { return NO; } return YES; }

第二种方法:继承

-(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; }

以上的代码都是在一个自定义的UIScrollView上的,重写上面的方法便可。而后让横向滚动的scrollView继承这个自定义UIScrollView就OK了。事件

原理:
scrollView的pan手势会让系统的pan手势失效,因此咱们只须要在系统手势失效且scrollView的位置在初始位置的时候让两个手势同时启用就能够了图片

相关文章
相关标签/搜索