解决滑动手势与ScrollView等滑动手势冲突的问题

MTResolveConflictPanGestureRecognizer.h

#import 


typedef NS_ENUM(NSInteger, MTPanDirection) {
    MTPanDirectionAny = 0,
    MTPanDirectionHorizontal,
    MTPanDirectionVertical
};

NS_ASSUME_NONNULL_BEGIN

@interface MTResolveConflictPanGestureRecognizer : UIPanGestureRecognizer

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

@property (nonatomic, assign) MTPanDirection allowedDirection;


@end

NS_ASSUME_NONNULL_END

MTResolveConflictPanGestureRecognizer.m

#import 

int const static kDirectionPanThreshold = 5;

@interface MTResolveConflictPanGestureRecognizer()

@property (nonatomic, assign) MTPanDirection currentDirection;
@property (nonatomic, assign) CGPoint beginP;

@end

@implementation MTResolveConflictPanGestureRecognizer

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
    
    if (_autoLock) {
        _currentDirection = MTPanDirectionAny;
        _beginP = [[touches anyObject] locationInView:self.view];
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];
    
    if (!_autoLock) return;
    
    if (self.allowedDirection == self.currentDirection) {
        return;
    }
    
    CGPoint nowPoint = [[touches anyObject] locationInView:self.view];
    if (fabs(nowPoint.x-_beginP.x) < kDirectionPanThreshold &&
        fabs(nowPoint.y-_beginP.y) < kDirectionPanThreshold) {
        return;
    }
    
    if (_currentDirection == MTPanDirectionAny) {
        if (fabs(nowPoint.x - _beginP.x) - fabs(nowPoint.y - _beginP.y) > kDirectionPanThreshold) {
            _currentDirection = MTPanDirectionHorizontal;
        } else {
            _currentDirection = MTPanDirectionVertical;
        }
        
        if (self.allowedDirection != self.currentDirection) {
            self.state = UIGestureRecognizerStateFailed;
        }
    }
}


@end

在需要用到的地方直接集成该手势类就行!

使用举例:

MTResolveConflictPanGestureRecognizer * panGesture = [[MTResolveConflictPanGestureRecognizer alloc] initWithTarget:self action:@selector(onPanGestureRecognized:)];
        panGesture.autoLock = YES;
        panGesture.allowedDirection = MTPanDirectionVertical;
        panGesture.maximumNumberOfTouches = 1;
        panGesture.minimumNumberOfTouches = 1;
        
        [self addGestureRecognizer:panGesture];

你可能感兴趣的:(解决滑动手势与ScrollView等滑动手势冲突的问题)