iOS 侧滑返回手势与Scrollview冲突的解决办法

苹果在iOS7.0以后推出了一个侧滑返回手势,当导航栏Push到下一页时,可以通过侧滑手势pop到上一页,这大大提高了用户的体验度,同时增加了可玩性。
然而有些时候,当你push到另一个界面后,如果该界面有Scrollview或继承于Scrollview(tableview,collectionview)的控件,这时你可能会发现返回手势失效了,这个是为什么喃?
经过我多番验证,原来是这个控件拦截了手势(这个地方不清楚的小伙伴可以去看看手势的响应链)。当然,这个对app功能没什么影响,但是基于用户体验来说,这是一个很坏的体验!!

方案一:解决办法就是对Scrollview加个Category,重写它代理的方法,让手势能够传递下去
  • 第一步,新建一个Scrollview的CateGory
iOS 侧滑返回手势与Scrollview冲突的解决办法_第1张图片
2B2A854A-DC2B-473F-8B56-FE40AE008A4F.png
  • 第二步,重写这个方法,让手势能够传递下去
iOS 侧滑返回手势与Scrollview冲突的解决办法_第2张图片
0C94D23F-A7F9-4ED7-AE89-B2DDC2DAE8B1.png

-第三步,就是对手势进行自定义,可以根据需求设置(可以设置侧滑手势的有效范围)

iOS 侧滑返回手势与Scrollview冲突的解决办法_第3张图片
00154AED-3942-41BC-80B4-D00C2755130A.png

-最后你就会见证神奇的一刻了。

最后附上代码:

#define IPHONE_H [UIScreen mainScreen].bounds.size.height //屏幕的高度
#define IPHONE_W [UIScreen mainScreen].bounds.size.width // 屏幕的宽度
//是否支持多手势触发,返回YES,则可以多个手势一起触发方法,返回NO则为互斥.
//是否允许多个手势识别器共同识别,一个控件的手势识别后是否阻断手势识别继续向下传播,默认返回NO;如果为YES,响应者链上层对象触发手势识别后,如果下层对象也添加了手势并成功识别也会继续执行,否则上层对象识别后则不再继续传播
//一句话总结就是此方法返回YES时,手势事件会一直往下传递,不论当前层次是否对该事件进行响应。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    
    if ([self panBack:gestureRecognizer]) {
        return YES;
    }
    return NO;
    
}

//location_X可自己定义,其代表的是滑动返回距左边的有效长度
- (BOOL)panBack:(UIGestureRecognizer *)gestureRecognizer {
    
    //是滑动返回距左边的有效长度
    int location_X =0.15*IPHONE_W;
    
    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];
            
            //这是允许每张图片都可实现滑动返回
            int temp1 = location.x;
            int temp2 =IPHONE_W;
            NSInteger XX = temp1 % temp2;
            if (point.x >0 && XX < location_X) {
                return YES;
            }
            //下面的是只允许在第一张时滑动返回生效
            //            if (point.x > 0 && location.x < location_X && self.contentOffset.x <= 0) {
            //                return YES;
            //            }
        }
    }
    return NO;
    
}

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

附上最后效果图

11111111.gif

方案二:简单暴力,只需要在当前控制器加上几行代码就能解决这个问题

直接上代码
   NSArray *gestureArray = self.navigationController.view.gestureRecognizers;
    
    for (UIGestureRecognizer *gestureRecognizer in gestureArray) {
        
        if ([gestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
            
            [self.scrollView.panGestureRecognizer requireGestureRecognizerToFail:gestureRecognizer];
            
        }
        
    }

你可能感兴趣的:(iOS 侧滑返回手势与Scrollview冲突的解决办法)