IOS开发 手势冲突问题

UIGestureRecognizer手势基本介绍(手势冲突在下面,可以根据目录跳转⬇️)

  • 基于UIResponder的触摸事件TouchBeginTouchMove
  • 可以轻松在UIView上面做一些常用手势
	// 手势合集,都继承于UIGestureRecognizer
	UITapGestureRecognizer(点按)
	UIPanGestureRecognizer(拖动)
	UIPinchGestureRecognizer(捏合)
	UIRotationGestureRecognizer(旋转)
	UILongPressGestureRecognizer(长按)
	​UISwipeGestureRecognizer(轻扫)

UIGestureRecognizer 所有手势的父类

  • 可以根据state判断手势的状态,所有手势共有的属性
@property(nonatomic,readonly) UIGestureRecognizerState state; //手势的状态

typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
    UIGestureRecognizerStatePossible,
    UIGestureRecognizerStateBegan,
    UIGestureRecognizerStateChanged,
    UIGestureRecognizerStateEnded,
    UIGestureRecognizerStateCancelled,
    UIGestureRecognizerStateFailed,
    UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded 
}

属性

@property(nonatomic) BOOL cancelsTouchesInView;       // 默认YES,触发手势后取消UIResponder的识别
@property(nonatomic) BOOL delaysTouchesBegan;         // 默认NO,延迟UIResponder的识别,等手势触发完再开始
@property(nonatomic) BOOL delaysTouchesEnded;         // 默认YES,延迟UIResponder识别结束0.15s

常用代理方法

// 手势是否相应
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    return YES;
}

// 默认为NO,手势是否穿透使用
// 返回YES保证可以同时识别手势,返回NO无法保证拒绝穿透,因为其他手势的代理方法有可能是YES
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return NO;
}

UITapGestureRecognizer 敲击 点按

/// 需要连续点击次数,才能生效;例如设置为2,需要双击才能生效
@property (nonatomic) NSUInteger  numberOfTapsRequired;
/// 几个手指点击才生效
@property (nonatomic) NSUInteger  numberOfTouchesRequired API_UNAVAILABLE(tvos); 

UIPanGestureRecognizer 拖动

/// 获取CGPoint
- (CGPoint)translationInView:(nullable UIView *)view;
/// 设置translation
- (void)setTranslation:(CGPoint)translation inView:(nullable UIView *)view;
-(void)pan:(UIPanGestureRecognizer *)sender{
	CGPoint point = [sender translationInView:sender.view];
	self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform,point.x,point.y);
	// 恢复到初始状态
	[sender setTranslation:CGPointZero inView:sender.view];
}

UILongPressGestureRecognizer 长按

/// Default is 0.5. 长按生效时间
@property (nonatomic) NSTimeInterval minimumPressDuration; 
/// Default is 10. 手指移动的像素,生效的误差范围
@property (nonatomic) CGFloat allowableMovement;           

UIRotationGestureRecognizer 旋转

/// 旋转的角度,一直叠加
@property (nonatomic)          CGFloat rotation;
@property (nonatomic,readonly) CGFloat velocity;
- (void)rotation:(UIRotationGestureRecognizer *)sender{
	// 方法一:可以直接使用
	self.imageView.transform = CGAffineTransformMakeRotation(sender.rotation);
	// 方法二:会出现无限累加的情况,需要每次运行结束把sender.rotation = 0;
	self.imageView.transform = CGAffineTransformRotation(sender.rotation);
}

UIPinchGestureRecognizer 捏合

/// 捏合的程度 也会很出现Rotation的情况,需要sender.scale = 1或者使用Make函数
@property (nonatomic)          CGFloat scale; 
@property (nonatomic,readonly) CGFloat velocity;

UISwipeGestureRecognizer 轻扫

typedef NS_OPTIONS(NSUInteger, UISwipeGestureRecognizerDirection) {
    UISwipeGestureRecognizerDirectionRight = 1 << 0,//默认从左往右滑动
    UISwipeGestureRecognizerDirectionLeft  = 1 << 1,
    UISwipeGestureRecognizerDirectionUp    = 1 << 2,
    UISwipeGestureRecognizerDirectionDown  = 1 << 3
};

@property(nonatomic) NSUInteger  numberOfTouchesRequired API_UNAVAILABLE(tvos);
/// 可以通过更改扫的方向
@property(nonatomic) UISwipeGestureRecognizerDirection direction;

UIResponder和UIControl对触碰事件的相应

  • UIButton为例继承关系:UIButton -> UIControl -> UIView -> UIResponder -> NSObject
  • UIView为例:UIView -> UIResponder -> NSObject

UIResponder会判断是否相应触碰事件Touch,不响应则默认向下传递
UIControl则直接拦截触碰事件Touch,不向下传递

iOS | 事件传递及响应链
iOS | 响应链及手势识别

判断或者限制手势生效区域

在相应判断方法中可以对点击的点位置和UIView进行检查限制

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
	// 点击的UIView
    UIView *view = touch.view;
    // 点击的点位置
    CGPoint point = [touch locationInView:touch.view];
    // 检查通过则返回YES
    return YES;
}

手势嵌套使用冲突问题理解

![在这里插入图片描述](https://img-blog.csdnimg.cn/a31bdf7a495d45fe8e9bcec3e6512e49.png


两个UIView嵌套使用,灰色UIView在绿色UIView内部,即为父子关系

默认情况下,同种类型的手势只触发一个且优先深层次的手势

绿色添加Tap ,灰色无手势
点击绿色触发绿色Tap
点击灰色触发绿色Tap
绿色添加Tap,灰色添加Tap
点击绿色触发绿色Tap
点击灰色触发灰色Tap
绿色添加TapPan,灰色添加Tap
点击绿色触发绿色Tap
点击灰色触发灰色Tap
拖动绿色触发绿色Pan
拖动灰色触发绿色Pan
绿色灰色都添加TapPan
点击绿色触发绿色Tap
点击灰色触发灰色Tap
拖动绿色触发绿色Pan
拖动灰色触发灰色Pan

两者任意一个开启手势穿透,则全部手势都可以触发

绿色添加Tap,灰色添加Tap
点击绿色触发绿色Tap
点击灰色触发绿色Tap和灰色Tap

两个UIView为兄弟关系,手势穿透失效

绿色添加Tap,灰色添加Tap
点击绿色触发绿色Tap
点击灰色触发灰色Tap
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值