手势识别在iOS中非常重要,它极大地提高了移动设备的使用便捷性。UIGestureRecognizer是一个定义基本手势的抽象类,其扩展类有UITapGestureRecognizer,UIPinchGestureRecognizer,UIRotationGestureRecognizer,UISwipeGestureRecognizer,UIPanGestureRecognizer,UILongPressGestureRecognizer。借助这些类,可以实现UIView对象的一些操作如对象放大缩小、移动、旋转、滑动、轻击等。
知识点:
1、点击手势UITapGestureRecognizer
2、捏合手势,常用于缩放UIPinchGestureRecognizer
3、旋转手势UIRotationGestureRecognizer
4、轻扫手势UISwipeGestureRecognizer
5、拖动手势,慢速移动UIPanGestureRecognizer
6、长按手势UILongPressGestureRecognizer
这些操作的目的都是用来修改UIView对象的frame,center,bounds属性,还有一个Transform属性。
说明:
一个手势只能对应一个View,但是一个View可以有多个手势。(模拟器测试捏合和旋转手势时,按住 option 键,再用触摸板或鼠标操作)
离散型手势&连续型手势
UITapGestureRecognizer是六种手势识别中唯一的离散型手势,离散型手势的特点是:一旦识别就无法取消,而且只会调用一次手势操作事件(初始化手势时指定的回调方法)。其他五种手势是连续型手势,连续型手势的特点是:会多次调用手势操作事件,而且在连续手势识别后可以取消手势。
离散型手势UITapGestureRecognizer要么被识别,要么失败,点击(假设点击次数设置为1,并且没有添加长按手势)下去一次不松开则此时什么也不会发生,松开手指立即识别并调用操作事件。
连续型手势相对要负责一些,以旋转手势为例,如果两个手指点下去不做任何操作,此时并不能识别手势(因为还没旋转)但是其实已经触发了触摸开始事件;如果旋转被识别,也就会调用相应的操作事件。
手势状态枚举如下:
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
UIGestureRecognizerStatePossible, // 尚未识别是何种手势操作(但可能已经触发了触摸事件),默认状态
UIGestureRecognizerStateBegan, // 手势已经开始,此时已经被识别,但是这个过程中可能发生变化,手势操作尚未完成
UIGestureRecognizerStateChanged, // 手势状态发生转变
UIGestureRecognizerStateEnded, // 手势识别操作完成(此时已经松开手指)
UIGestureRecognizerStateCancelled, // 手势被取消,恢复到默认状态
UIGestureRecognizerStateFailed, // 手势识别失败,恢复到默认状态
UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // 手势识别完成,同UIGestureRecognizerStateEnded
};
1.UITapGestureRecognizer
源代码
先添加手势的View:
self.imgView = [[UIImageView alloc] initWithFrame:CGRectMake(66, 86, 200, 200)];
_imgView.image = [UIImage imageNamed:@"aa"];
_imgView.userInteractionEnabled = YES;
[self.view addSubview:_imgView];
添加手势:
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[_imgView addGestureRecognizer:tap];
手势方法:
- (void)handleTap:(UIGestureRecognizer *)gesture{
NSLog(@"tap");
}
2.UIPinchGestureRecognizer
源代码
- (void)pinch{UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
[_imgView addGestureRecognizer:pinch];
}
- (void)handlePinch:(UIPinchGestureRecognizer *)gesture{
NSLog(@"pinch");
gesture.view.transform = CGAffineTransformScale(gesture.view.transform, gesture.scale, gesture.scale);
gesture.scale = 1;
}
3.UIRotationGestureRecognizer
源代码
- (void)rotation{UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(handleRotation:)];
[_imgView addGestureRecognizer:rotation];
}
- (void)handleRotation:(UIRotationGestureRecognizer *)gesture{
gesture.view.transform = CGAffineTransformRotate(gesture.view.transform, gesture.rotation);
gesture.rotation = 0;
}
4.UISwipeGestureRecognizer(默认清扫方向为右)
源代码
- (void)swipe{
UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
rightSwipe.direction = UISwipeGestureRecognizerDirectionLeft;
UISwipeGestureRecognizer *leftSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
leftSwipe.direction = UISwipeGestureRecognizerDirectionRight;
[_imgView addGestureRecognizer:rightSwipe];
[_imgView addGestureRecognizer:leftSwipe];
}
- (void)handleSwipe:(UISwipeGestureRecognizer *)gesture{
switch (gesture.direction) {
case UISwipeGestureRecognizerDirectionRight:
NSLog(@"swipe right");
break;
case UISwipeGestureRecognizerDirectionLeft:
NSLog(@"swipe left");
break;
case UISwipeGestureRecognizerDirectionUp:
NSLog(@"swipe up");
break;
case UISwipeGestureRecognizerDirectionDown:
NSLog(@"swipe down");
break;
default:
break;
}
}
5.UIPanGestureRecognizer
源代码
- (void)pan{UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[_imgView addGestureRecognizer:pan];
}
- (void)handlePan:(UIPanGestureRecognizer *)gesture{
CGPoint translation = [gesture translationInView:_imgView];
gesture.view.center = CGPointMake(gesture.view.center.x + translation.x, gesture.view.center.y + translation.y);
[gesture setTranslation:CGPointZero inView:_imgView];
}
拖动视图需要用到一个方法:
CGPoint translation = [gesture translationInView:_imgView];
每一次拖动操作状态,都会获取到translatedPoint,从开始到结束。它是一个绝对值,可以看着在”_imgView“对应的坐标体系中,拖动的视图对象center的移动开始和结束的点差。
简单处理过程:
CGPoint translatedPoint = [gesture translationInView:_imgView];
CGFloat x = gesture.view.center.x +translation.x;
CGFloat y = gesture.view.center.y +translation.y;
gesture.view.center = CGPointMake(x, y);
[gesture setTranslation:CGPointMake(0, 0) inView:self.testPanView];
首先获取到移动点的值,然后算一下视图的center值,相加一下,就得到在self.view坐标体系中,视图该移动到那个center上,一次结束就清零一次。因为拖动操作持续进行,所以,这个过程会持续执行。
稍微复杂点的处理过程,会捕获到拖动开始,移动,结束等几个状态下的translatedPoint的值。然后做一下逻辑处理,如视图不能溢出self.view的坐标系中,如在结束时会根据方向自动滑动到某个位置。可以在handlePan2:方法中找到这些逻辑的实现代码。
6.UILongPressGestureRecognizer
源代码
- (void)longPress{
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
[_imgView addGestureRecognizer:longPress];
}
- (void)handleLongPress:(UILongPressGestureRecognizer *)gesture{
NSLog(@"长按");
}
参考链接:http://blog.csdn.net/majiakun1/article/details/17333683
http://blog.csdn.net/totogo2010/article/details/8615940