手势识别
- 之前监听触摸事件的做法
自定义
一个view- 实现view的
touches...
方法,在方法内部实现具体处理代码
- 通过
touches...
方法监听view触摸事件,有很明显的几个缺点
必须
得自定义view- 由于是在view内部的
touches...
方法中监听触摸事件,因此默认情况下,无法让其他外界对象监听view内部的触摸事件 无法
区分用户的具体手势
行为
- iOS 3.2之后,苹果推出了手势识别功能(Gesture Recognizer),在触摸事件处理方面,大大简化了开发者的开发难度
- UIGestureRecognizer是一个
抽象类
,定义了所有手势的基本行为,使用它的子类才能处理具体的手势 常见手势
- UI
Tap
GestureRecognizer(敲击
) - UI
Pinch
GestureRecognizer(捏合,用于缩放
) - UI
Pan
GestureRecognizer(拖拽
) - UI
Swipe
GestureRecognizer(轻扫
) - UI
Rotation
GestureRecognizer(旋转
) - UI
Long
PressGestureRecognizer(长按
)
- UI
手势使用演示
// 创建手势识别器对象
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapIconView:)];
// 连续敲击2次
tap.numberOfTapsRequired = 2;
// 需要2根手指一起敲击
tap.numberOfTouchesRequired = 2;
// 添加手势识别器到对应的view上,那么就可以在此view上应用对应的手势
[self.iconView addGestureRecognizer:tap];
通过
手势状态
可以在不同状态时做对应事情- UIGestureRecognizerState
Possible
没有触摸事件发生
,所有手势识别的默认状态
- UIGestureRecognizerState
Began
- 一个手势已经开始但尚未改变或者完成时
- UIGestureRecognizerState
Changed
- 手势状态改变
- UIGestureRecognizerState
Ended
- 手势完成
- UIGestureRecognizerState
Cancelled
- 手势取消,
恢复至Possible
状态
- 手势取消,
- UIGestureRecognizerState
Failed
- 手势失败,
恢复至Possible
状态
- 手势失败,
- UIGestureRecognizerState
Recognized
= UIGestureRecognizerStateEnded
- UIGestureRecognizerState
同时支持多个手势
是通过代理完成- 要同时支持的每个手势都必须设置代理
- 实现
UIGestureRecognizerDelegate
协议
// 每个手势设置代理
// 是否允许同时支持多个手势,默认是不支持多个手势
// 返回YES表示支持多个手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
- 要一个控件支持多个方向的
轻扫手势
,必须创建多个轻扫手势,一个轻扫手势只支持一个方向(设置左右方向是能同时支持的,同时设置上下方向也是支持的) - 需要
复位
的手势- 旋转手势
- 缩放手势
- 拖拽手势
#pragma mark - 旋转手势
- (void)setupRotation
{
UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotation:)];
// 设置代理
rotation.delegate = self;
[self.imageView addGestureRecognizer:rotation];
}
// 默认传递的旋转的角度都是相对于最开始的位置
- (void)rotation:(UIRotationGestureRecognizer *)rotation
{
self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, rotation.rotation);
// 复位,不然就会在原来的角度上累加,导致旋转的很快
// 比如,第一次旋转了10°,第二次旋转的3°,实际却旋转了13°
rotation.rotation = 0;
}
#pragma mark - 捏合
- (void)setupPinch
{
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
// 设置代理
pinch.delegate = self;
[self.imageView addGestureRecognizer:pinch];
}
- (void)pinch:(UIPinchGestureRecognizer *)pinch
{
self.imageView.transform = CGAffineTransformScale(self.imageView.transform, pinch.scale, pinch.scale);
// 复位,不然就会在原来的缩放比例上继续累加,导致缩放的很快
// 比如,第一次缩小到0.8,如果不复位,第二次也缩小0.8,实际缩小了0.64
pinch.scale = 1;
}
#pragma mark - 拖拽
- (void)setupPan
{
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];
// 设置代理
pan.delegate = self;
[self.imageView addGestureRecognizer:pan];
}
- (void)pan:(UIPanGestureRecognizer *)pan
{
// 移动视图
// 获取手势的移动,也是相对于最开始的位置
CGPoint transP = [pan translationInView:self.imageView];
self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, transP.x, transP.y);
// 复位,如果不复位就会在原来的平移基础上累加,导致平移过快
// 比如:第一次移动的10个点,如果不复位,第二次移动了5个点,实际上却移动了15个点
[pan setTranslation:CGPointZero inView:self.imageView];
}