iOS scrollview 嵌套滑动冲突的处理

最近公司需要实现多个scrollView的联动处理,遇到了滑动手势的冲突问题,现将几个关键点记录

首先看下UIGestureRecognizerDelegate的代理方法

// called when the recognition of one of gestureRecognizer or otherGestureRecognizer would be blocked by the other
// return YES to allow both to recognize simultaneously. the default implementation returns NO (by default no two gestures can be recognized simultaneously)
//
// note: returning YES is guaranteed to allow simultaneous recognition. returning NO is not guaranteed to prevent simultaneous recognition, as the other gesture's delegate may return YES
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;

是否支持多手势触发,返回YES,则可以多个手势一起触发方法,返回NO则为互斥

如果tableView中放置了一个collectionView,自定义tableView的子类,可在实现文件中如下设置

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if ([self checkIsNestContentScrollView:(UIScrollView *)gestureRecognizer.view] || [self checkIsNestContentScrollView:(UIScrollView *)otherGestureRecognizer.view]) {
        //如果交互的是嵌套的contentScrollView,证明在左右滑动,就不允许同时响应
        return NO;
    }
    return [gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]];
}
- (BOOL)checkIsNestContentScrollView:(UIScrollView *)scrollView
{
    for (GCGiftContentView *listView in self.pagerView.validListDict.allValues) {
        if (listView.collectionView == scrollView) {
            return YES;
        }
    }
    return NO;
}

手势滑动屏幕需要获取手指滑动方向的解决方案
在scrollView的子类中实现

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
   if ([gestureRecognizer isMemberOfClass:NSClassFromString(@"UIScrollViewPanGestureRecognizer")]) {
            CGFloat velocityX = [(UIPanGestureRecognizer *)gestureRecognizer velocityInView:gestureRecognizer.view].x;
            CGFloat velocityY = [(UIPanGestureRecognizer *)gestureRecognizer velocityInView:gestureRecognizer.view].y;
            if (velocityX > 0) {
                //x大于0就是往右滑
            } else if (velocityX < 0) {
                //x小于0就是往左滑
            }
            if (velocityY > 0) {
                // y大于0就是手指从下往上滑
            } else {
                // y大于0就是手指从上往下滑
            }
        }
    return YES;
}

其中 用于获取手指在屏幕上的滑动速度 单位是points/second

// velocity of the pan in points/second in the coordinate system of the specified view
- (CGPoint)velocityInView:(nullable UIView *)view;                           

以上方法只能在手势刚开始触发时获取即将滑动的方向,如果手指贴着屏幕一直不松手,此时结束时会回调此代理

// called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;

decelerate == NO 手指松开后UI不再滑动,此时不回调 scrollViewDidEndDecelerating
decelerate == YES 手指松开后UI惯性滑动一段距离,滑动结束回调 scrollViewDidEndDecelerating

你可能感兴趣的:(iOS scrollview 嵌套滑动冲突的处理)