iOS中UIView的Pan手势和UIScrollView滚动手势的冲突解决方案

tableView滚动视图中包含播放器窗口,播放器控制层包含了上下滑动手势调节音量和屏幕亮度功能,与tableView的上下滚动手势冲突。导致播放器窗口上下滚动时,tableView不滚动问题,影响用户体验。

因此本内容主要是为了处理UIScrollView的子视图上添加UIPanGestureRecognizer后,导致上下滑动该子视图时UIScrollView无法跟随上下滚动的情况。

新建 UIPanGestureRecognizer的子类 

@interface ZFPanGestureRecognizer : UIPanGestureRecognizer

/**
 是否自动锁住手势方向,默认为NO
 如果设置成YES,则在手势开始时根据xy的偏移量大小来确定最可能的滑动方向,并在手势有效期内保持这个方向上的有效性
 */
@property (nonatomic, assign) BOOL  autoLock;

@end

然后实现touchesMoved方法,可以在该方法中自定义,是否支持滑动效果。

#import "ZFPanGestureRecognizer.h"

typedef NS_ENUM(NSInteger, IXPanDirection) {
    IXPanDirectionAny = 0,
    IXPanDirectionHor,
    IXPanDirectionVer
};

@interface ZFPanGestureRecognizer ()

@property (nonatomic, assign) IXPanDirection    direction;
@property (nonatomic, assign) CGPoint   beginP;

@end

@implementation ZFPanGestureRecognizer

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    [super touchesBegan:touches withEvent:event];
    if (_autoLock) {
        _direction = IXPanDirectionAny;
        _beginP = [[touches anyObject] locationInView:self.view];
    }
}

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    [super touchesMoved:touches withEvent:event];
    if (!_autoLock && _direction != IXPanDirectionAny) return;
    
    CGPoint nowPoint = [[touches anyObject] locationInView:self.view];
    if (_direction == IXPanDirectionAny) {
        
        if (fabs(nowPoint.x - _beginP.x) > fabs(nowPoint.y - _beginP.y)) {
            _direction = IXPanDirectionHor;
        } else {
            if (_beginP.x > self.view.bounds.size.width*0.5) {
                _direction = IXPanDirectionVer;
                self.state = UIGestureRecognizerStateFailed;
            }
        }
    }
}

使用我们的自定义pan手势

ZFPanGestureRecognizer * ixPan = [[ZFPanGestureRecognizer alloc] initWithTarget:self action:@selector(panAction:)]; 
ixPan.autoLock
= YES;
[view addGestureRecognizer:ixPan];

 

posted on 2020-12-03 15:32  大圣ios博客  阅读(1719)  评论(0编辑  收藏  举报