1. UIGestureRecognizer简介
用户手指在屏幕上触碰、划过等吧行为,被统称为手势。iOS3.2之后,UIGestureRecognizer提供如下子类:
- UITapGestureRecognizer(点按)
- UIPinchGestureRecognizer(捏合)
- UIRotationGestureRecognizer(旋转)
- UISwipeGestureRecognizer(轻扫)
- UIPanGestureRecognizer(拖动)
- UILongPressGestureRecognizer(长按)
2. 手势状态
在六种手势识别中,只有一种手势是离散型手势,他就是 UITapGestureRecognizer。这种手势特点是:一旦识别就无法取消,而且只会调用一次手势操作事件(初始化手势时指定的回调方法)。其它五种手势是连续型手势,连续型手势的特点就是:会多次调用手势操作事件,而且在连续手势识别后可以取消手势。
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
UIGestureRecognizerStatePossible, // 尚未识别是何种手势操作(但可能已经触发了触摸事件),默认状态
UIGestureRecognizerStateBegan, // 手势已经开始,此时已经被识别,但是这个过程中可能发生变化,手势操作尚未完成
UIGestureRecognizerStateChanged, // 手势状态发生转变
UIGestureRecognizerStateEnded, // 手势识别操作完成(此时已经松开手指)
UIGestureRecognizerStateCancelled, // 手势被取消,恢复到默认状态
UIGestureRecognizerStateFailed, // 手势识别失败,恢复到默认状态
UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // 手势识别完成,同UIGestureRecognizerStateEnded
};
- 离散型手势 UITapGestureRecgnizer 要么被识别,要么失败,点按(假设点按次数设置为1,并且没有添加长按手势)下去一次不松开则此时什么也不会发生,松开手指立即识别并调用操作事件,并且状态为3(已完成)。
- 但是连续型手势要复杂一些,拿旋转手势来说,如果两个手指点下去不做任何操作,此时并不能识别手势(因为还没旋转)但是其实已经触发了触摸开始事件,此时处于状态0;如果此时旋转会被识别,也就会调用对应的操作事件,同时状态变成1(手势开始),但是状态1只有一瞬间;紧接着状态变为2(因为我们的旋转需要持续一会),并且重复调用操作事件(如果在事件中打印状态会重复打印2);松开手指,此时状态变为3,并调用1次操作事件。
3.UIGestureRecognizer作为手势处理器的基类,提供如下常用方法和属性:
- (CGPoint)locationInView:(nullable UIView*)view;
返回该手势在view控件中的触碰位置
- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view;
返回该手势中第touchIndex 个触碰点在view控件中的触碰位置
numberOfTouches: 返回该手势触碰点的数量(即几个手指触碰)
state: 获取该手势所处状态,比如刚开始处于,手势结束处于
view: 返回激发该手势的UI控件
4.使用手势的步骤
1.根据程序要处理的手势创建对应的手势处理器对象。需要指定target和action参数,当该控件上发生触碰手势后,target对象的action方法就会被激发
2.如果该UI控件不允许交互,则userInteractionEnabled设为NO.如果支持多点触控multipleTouchEnabled设为YES。
3.调用addGestureRecognizer添加手势处理器.
5.实例
5.1 UITapGestureRecognizer(点按)
- (void)viewDidLoad{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
//设置只处理2个手指的触碰事件
gesture.numberOfTouchesRequired = 2;
[self.view addGestureRecognizer:gesture];
}
//实现手势处理器的方法,该方法应该声明一个形参。
//当该方法被激发时,手势处理器会作为参数传给该方法的参数。
- (void)handleTap:(UITapGestureRecognizer*)gesture{
NSUInteger touchNum = gesture.numberOfTouches;
NSUInteger tapNum = gesture.numberOfTapsRequired;
NSLog(@"用户使用%ld个手指进行触碰,触碰次数为:%ld",touchNum,tapNum);
}
5.2 UIPinchGestureRecognizer(捏合)
velocity:获取捏合速度
scale:获取捏合比例
- (void)viewDidLoad{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
//支持多点触碰
self.view.multipleTouchEnabled = YES;
UIPinchGestureRecognizer* gesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
[self.view addGestureRecognizer:gesture];
}
// 实现手势处理器的方法,该方法应该声明一个形参。
// 当该方法被激发时,手势处理器会作为参数传给该方法的参数。
- (void) handlePinch:(UIPinchGestureRecognizer*)gesture{
// 获取用户捏合的速度和比例
CGFloat velocity = gesture.velocity;
CGFloat scale = gesture.scale;
NSLog(@"用户捏合的速度为%g、比例为%g",velocity,scale);
}
5.3 UIRotationGestureRecognizer(旋转)