自定义OneFingerRotationGestureRecognizer与UITapGestureRecognizer冲突求助
解决圆形滑块旋转手势与点击手势的冲突问题
我来帮你搞定这个手势冲突的麻烦!这种自定义手势和系统手势抢触发的情况太常见了,给你几个亲测有效的方案,按需选就行:
方案一:设置手势依赖(最推荐,符合系统逻辑)
直接让点击手势必须等旋转手势失败后才能触发,代码超简单:
// 假设你已经有了rotationGesture(自定义旋转手势)和tapGesture(点击手势)的引用 [self.tapGesture requireGestureRecognizerToFail:self.rotationGesture];
原理是告诉系统:只有当旋转手势确定识别失败(比如用户只是点击,没有任何拖动动作),点击手势才可以触发。这样拖动时旋转手势会优先被识别,点击手势就不会乱跳了。
方案二:在自定义旋转手势里主动取消点击手势
如果你想更主动控制,可以在自定义的OneFingerRotationGestureRecognizer中,一旦检测到用户开始拖动,就直接取消点击手势的识别:
// 在OneFingerRotationGestureRecognizer的touchesBegan:withEvent:方法中添加 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [super touchesBegan:touches withEvent:event]; // 遍历当前视图的所有手势,找到点击手势并取消 for (UIGestureRecognizer *gesture in self.view.gestureRecognizers) { if ([gesture isKindOfClass:[UITapGestureRecognizer class]]) { // iOS10+ 可以直接调用cancelGesture if (@available(iOS 10.0, *)) { [gesture cancelGesture]; } else { // 低版本用enabled临时禁用再恢复 gesture.enabled = NO; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ gesture.enabled = YES; }); } } } }
或者在手势状态变为UIGestureRecognizerStateBegan时处理,效果是一样的。
方案三:优化自定义旋转手势的触发灵敏度
让旋转手势更快进入"开始识别"状态,比如只要用户有微小拖动就触发,不给点击手势留机会:
// 在OneFingerRotationGestureRecognizer的touchesMoved:withEvent:方法中添加 - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { [super touchesMoved:touches withEvent:event]; UITouch *touch = touches.anyObject; CGPoint currentPoint = [touch locationInView:self.view]; CGPoint startPoint = [touch previousLocationInView:self.view]; // 计算移动距离,超过2pt就判定为拖动,触发旋转手势 CGFloat moveDistance = hypot(currentPoint.x - startPoint.x, currentPoint.y - startPoint.y); if (moveDistance > 2 && self.state == UIGestureRecognizerStatePossible) { self.state = UIGestureRecognizerStateBegan; } }
这样用户只要轻轻拖动,旋转手势就会立刻启动,系统就会优先处理旋转,忽略点击手势。
内容的提问来源于stack exchange,提问作者gasparuff
相关产品推荐
相关产品推荐

