监听触摸事件的做法
- 如果想监听一个view上面的触摸事件,之前的做法是
1.自定义一个view
2.实现view的touches方法,在方法内部实现具体处理代码 - 注意:通过touches方法监听view触摸事件,有很明显的几个缺点
1.必须得自定义view
2.由于是在view内部的touches方法中监听触摸事件,因此默认情况下,无法让其他外界对象监听view的触摸事件
3.不容易区分用户的具体手势行为 - iOS 3.2之后,苹果推出了手势识别功能(Gesture Recognizer),在触摸事件处理方面,大大简化了开发者的开发难度
UIGestureRecognizer的使用
1.什么是UIGestureRecognizer:
UIGestureRecognizer手势识别器
2.优点 :
利用UIGestureRecognizer,能轻松识别用户在某个view上面做的一些常见手势
3.注意点:
UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,使用它的子类才能处理具体的手势
4.UIGestureRecognizer的子类
UITapGestureRecognizer(敲击)
UIPinchGestureRecognizer(捏合,用于缩放)
UIPanGestureRecognizer(拖拽)
UISwipeGestureRecognizer(轻扫)
UIRotationGestureRecognizer(旋转)
UILongPressGestureRecognizer(长按)
手势的使用
注意:在使用手势时,涉及到形变的手势,不能使用make的transform方法
//self.imageV.transform = CGAffineTransformMakeTranslation(point.x, point.y);
因为当移动完毕后,在次点击拖动时,图片会回到最开始的位置,make的transform方法是相对于最原始的位置进行形变的而且只会执行一次,所以在拖动的时候,总是会回到起始点后,所以在拖动过程中,就会出现震颤的效果;
可以使用没有make的transform方法
self.imageV.transform = CGAffineTransformTranslate(self.imageV.transform, point.x, point.y);
因为这个方法的形变值,是相对上一次而非最初的状态的形变值,因此获取相对最初位置的偏移量是累加了之前的偏移量的值,获取到的偏移值会比实际的偏移值大很多,但是需要的偏移量是要相对图片最初位置的偏移量,所以,在这里需要调用setTranslation: inView:
方法,在拖动时,将上一次的偏移值清空,以获取拖动时相对初始位置的偏移值.
- 1.UITapGestureRecognizer(敲击)
/*************手势点按*************/
-(void)tapTestGes{
//创建手势
UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGes)];//当图片没有接受到手势的触摸事件后,不会调用tap方法
//给图片添加手势
[self.imageV addGestureRecognizer:tap];
}
//手势的方法
-(void)tapGes{
NSLog(@"%s",__func__);
}
- 2.UIPinchGestureRecognizer(捏合,用于缩放)
/*************捏合手势*************/
-(void)pinchGes{
UIPinchGestureRecognizer * pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGes:)];
pinch.delegate = self;
[self.imageV addGestureRecognizer:pinch];
}
//捏合手势的方法
-(void)pinchGes:(UIPinchGestureRecognizer *)pinch
{
self.imageV.transform = CGAffineTransformScale(self.imageV.transform, pinch.scale, pinch.scale);//如果缩放倍数写成常数,那么久只能放大或缩小
[pinch setScale:1];
}
- 3.UIPanGestureRecognizer(拖拽)
/*************拖动手势*************/
-(void)panGes{
UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGes:)];
[self.imageV addGestureRecognizer:pan];
}
//平移图片
-(void)panGes:(UIPanGestureRecognizer *)pan
{
//获取图片相对最开始时的自己的位置
CGPoint point = [pan translationInView:self.imageV];
self.imageV.transform = CGAffineTransformTranslate(self.imageV.transform, point.x, point.y);
//重置图片的移动距离(相对于上一次)
NSLog(@"%@",NSStringFromCGPoint(point));
[pan setTranslation:CGPointZero inView:self.imageV];
}
- 4.UISwipeGestureRecognizer(轻扫)
//设置轻扫方向
1.只有在同一水平方向上的手势可以拼接,不在同一水平方向上的手势不可以拼接
2.拼接以后只能识别图片被轻扫了,但不能识别往哪个方向轻扫
3.要想识别图片是往哪个方向轻扫了,需要添加两个轻扫手势对象,其中一个手势对象必须指明要滑动的方向
/*************轻扫手势*************/
-(void)swipeGes{
//创建轻扫手势
UISwipeGestureRecognizer * swipe1 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGes:)];
//设置轻扫方向
swipe1.direction = UISwipeGestureRecognizerDirectionLeft;
//给图片添加轻扫手势
[self.imageV addGestureRecognizer:swipe1];
//创建第二个轻扫手势
UISwipeGestureRecognizer * swipe2 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGes:)];
//给图片添加第二个轻扫手势
[self.imageV addGestureRecognizer:swipe2];
}
//轻扫手势方法的实现
-(void)swipeGes:(UISwipeGestureRecognizer *)swipe
{
if (swipe.direction == UISwipeGestureRecognizerDirectionLeft) {
NSLog(@"向左轻扫图片");
}else if (swipe.direction == UISwipeGestureRecognizerDirectionRight){
NSLog(@"向右轻扫图片");
}else{
NSLog(@"无法识别轻扫图片的方向");
}
}
- 5.UIRotationGestureRecognizer(旋转)
/*************旋转手势*************/
-(void)rotationGes{
UIRotationGestureRecognizer * rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationGes:)];
rotation.delegate = self;
[self.imageV addGestureRecognizer:rotation];
}
//旋转手势的方法
-(void)rotationGes:(UIRotationGestureRecognizer *)rotation
{
self.imageV.transform = CGAffineTransformRotate(self.imageV.transform, rotation.rotation);
[rotation setRotation:0];
}
- 6.UILongPressGestureRecognizer(长按)
/*************手势长按*************/
-(void)longPressGes
{
//创建长按手势
UILongPressGestureRecognizer * longP = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPGes:)];
//给图片添加长按手势
[self.imageV addGestureRecognizer:longP];
}
//当长按的时候会调用此方法
-(void)longPGes:(UILongPressGestureRecognizer *)longP
{
//判断长按手势的状态.因此,方法应该传入长按手势对象
if (longP.state == UIGestureRecognizerStateBegan) {
NSLog(@"开始长按");
}else if (longP.state == UIGestureRecognizerStateChanged){
NSLog(@"开始滑动");
}else if (longP.state == UIGestureRecognizerStateEnded){
NSLog(@"结束长按");
}
}
- 设置是否允许手指触摸,需要设置代理,并实现下面的代理方法
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
//获取当前触摸点的位置
CGPoint curP = [touch locationInView:self.imageV];
//设置可触摸的范围(左侧不可触摸,右侧可以触摸)
if (curP.x <= self.imageV.frame.size.width * 0.5) {
NSLog(@"%@",NSStringFromCGPoint(curP));
NSLog(@"不可以触摸");
return NO;
}else{
NSLog(@"%@",NSStringFromCGPoint(curP));
NSLog(@"可以触摸");
return YES;
}
- 设置是否允许接受多个手势,设置对应手势的代理,并实现下面的dialing方法
//实现代理方法
//同时执行多个手势操作
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}