UIGestureRecognizer手势基本介绍(手势冲突在下面,可以根据目录跳转⬇️)
- 基于
UIResponder
的触摸事件TouchBegin
、TouchMove
等 - 可以轻松在
UIView
上面做一些常用手势
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;
@property(nonatomic) BOOL delaysTouchesBegan;
@property(nonatomic) BOOL delaysTouchesEnded;
常用代理方法
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
return YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return NO;
}
UITapGestureRecognizer 敲击 点按
@property (nonatomic) NSUInteger numberOfTapsRequired;
@property (nonatomic) NSUInteger numberOfTouchesRequired API_UNAVAILABLE(tvos);
UIPanGestureRecognizer 拖动
- (CGPoint)translationInView:(nullable UIView *)view;
- (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 长按
@property (nonatomic) NSTimeInterval minimumPressDuration;
@property (nonatomic) CGFloat allowableMovement;
UIRotationGestureRecognizer 旋转
@property (nonatomic) CGFloat rotation;
@property (nonatomic,readonly) CGFloat velocity;
- (void)rotation:(UIRotationGestureRecognizer *)sender{
self.imageView.transform = CGAffineTransformMakeRotation(sender.rotation);
self.imageView.transform = CGAffineTransformRotation(sender.rotation);
}
UIPinchGestureRecognizer 捏合
@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 *view = touch.view;
CGPoint point = [touch locationInView:touch.view];
return YES;
}
手势嵌套使用冲突问题理解
![![在这里插入图片描述](https://img-blog.csdnimg.cn/a31bdf7a495d45fe8e9bcec3e6512e49.png](https://img-blog.csdnimg.cn/be4daee9f671429cb3cf78c508ffa683.png)
两个UIView
嵌套使用,灰色UIView
在绿色UIView
内部,即为父子关系
默认情况下,同种类型的手势只触发一个且优先深层次的手势
| 绿色添加Tap ,灰色无手势 |
---|
点击绿色 | 触发绿色Tap |
点击灰色 | 触发绿色Tap |
| 绿色添加Tap ,灰色添加Tap |
---|
点击绿色 | 触发绿色Tap |
点击灰色 | 触发灰色Tap |
| 绿色添加Tap 和Pan ,灰色添加Tap |
---|
点击绿色 | 触发绿色Tap |
点击灰色 | 触发灰色Tap |
拖动绿色 | 触发绿色Pan |
拖动灰色 | 触发绿色Pan |
| 绿色灰色都添加Tap 和Pan |
---|
点击绿色 | 触发绿色Tap |
点击灰色 | 触发灰色Tap |
拖动绿色 | 触发绿色Pan |
拖动灰色 | 触发灰色Pan |
两者任意一个开启手势穿透,则全部手势都可以触发
| 绿色添加Tap ,灰色添加Tap |
---|
点击绿色 | 触发绿色Tap |
点击灰色 | 触发绿色Tap和灰色Tap |
两个UIView
为兄弟关系,手势穿透失效
| 绿色添加Tap ,灰色添加Tap |
---|
点击绿色 | 触发绿色Tap |
点击灰色 | 触发灰色Tap |