一、手势识别与触摸事件

1、如果想监听一个view上面的触摸事件,可选的做法是:

(1)自定义一个view

(2)实现view的touches方法,在方法内部实现具体处理代码

2、通过touches方法监听view触摸事件,有很明显的几个缺点

(1)必须得自定义view

(2)由于是在view内部的touches方法中监听触摸事件,因此默认情况下,无法让其他外界对象监听view的触摸事件

(3)不容易区分用户的具体手势行为

3、iOS 3.2之后,苹果推出了手势识别功能(Gesture Recognizer),在触摸事件处理方面,大大简化了开发者的开发难度

二、手势识别——Gesture Recognizer

1、手势识别器:UIGestureRecognizer

(1)UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,使用它的子类才能处理具体的手势

(2)子类的继承和功能

图示:

2、手势识别的使用方法及步骤

(1)创建手势识别实例

(2)设置手势识别属性,例如手指数量,方向等

(3)将手势识别附加到指定的视图之上

(4)编写手势触发监听方法

(5)手势触发监听方法后,要还原手势识别实例的属性,比如:获取了缩放比例,然后给某个控件进行了缩放,最后再把缩放比例还原为1。这样后续的手势操作会从新开始,避免错误

3、手势识别的状态

(1)类似于触摸事件,手势识别实例包含了属性 state,可以区别此时手势的状态

(2)state属性为枚举类型:

<1> 没有触摸事件发生,所有手势识别的默认状态

UIGestureRecognizerStatePossible,

<2> 一个手势已经开始但尚未改变或者完成时

UIGestureRecognizerStateBegan, (类似于 touchesBegan)

<3> 手势状态改变

UIGestureRecognizerStateChanged, (类似于 touchesMoved)

<4> 手势完成

UIGestureRecognizerStateEnded, (类似于 touchesEnded)

<5> 手势取消,恢复至Possible状态

UIGestureRecognizerStateCancelled, (比如手指按下按钮,然后从其他地方抬起)

<6> 手势失败,恢复至Possible状态

UIGestureRecognizerStateFailed,

<7> 识别到手势结束

UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded

4、不同手势识别子类具有不同的属性或方法,几个重要的举例如下:

(1)在“轻点”手势中:

  <1> 需要连续敲击2次触发手势

  tap.numberOfTapsRequired = 2;

  <2> 需要2根手指一起敲击

  tap.numberOfTouchesRequired = 2;

(2)在“旋转”手势中:

  <1>获取用户旋转角度

  CGFloat rotation;

  

  <2>获取用户旋转速度

  CGFloat velocity

(3)在“轻扫”手势中:

  <1>扫动的方向,注意,一个轻扫手势识别对象,只能对应一个扫动方向

  UISwipeGestureRecognizerDirection

(4)在“拖拽”手势中:

  <1> 获取移动的距离 ,这个是对象方法

  - (CGPoint)translationInView:(nullable UIView *)view;

  <2>清除手势移动的距离(为了下次手势事件的正确计算)

 例: [pan setTranslation:CGPointZero inView:self.view];

5、实现多手势识别(比如缩放的同时可以旋转)

(1)设置手势识别器的代理

(2)实现相应的代理方法,支持多手势识别。

三、demo实例

1、图示

2、贴出部分代码

#pragma mark - 长按手势
- (IBAction)longPressBtnClick:(id)sender { //长按手势识别器,正常下会执行两次方法,不晓得为啥
UILongPressGestureRecognizer * longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longClick:)]; [self.view addGestureRecognizer:longPress];
//代理
longPress.delegate = self; } -(void)longClick:(UILongPressGestureRecognizer *)longPress
{ //根据状态判断
if(longPress.state==UIGestureRecognizerStateBegan)
{
NSLog(@"开始长按了~~"); } } #pragma mark - 旋转手势
- (IBAction)rotateBtnClick { UIRotationGestureRecognizer * rotate = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotateClick:)]; [self.view addGestureRecognizer:rotate]; //增加代理
rotate.delegate =self; } -(void)rotateClick:(UIRotationGestureRecognizer *)rotate
{ CGFloat ratation = rotate.rotation;
self.headerView.transform = CGAffineTransformRotate(self.headerView.transform, ratation); //清除掉累加的 rotation
rotate.rotation=;
} #pragma mark - 缩放手势
- (IBAction)pinchBtnClick { UIPinchGestureRecognizer * pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchClick:)]; [self.view addGestureRecognizer:pinch]; //增加代理
pinch.delegate = self; } -(void)pinchClick:(UIPinchGestureRecognizer *)pinch
{
CGFloat scale = pinch.scale;
self.headerView.transform = CGAffineTransformScale(self.headerView.transform, scale, scale); //同样清除
pinch.scale = ; } #pragma mark - 轻扫手势
- (IBAction)swipeBtnClick { UISwipeGestureRecognizer * swipe = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeClick:)]; //向右扫动手势
swipe.direction= UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipe]; UISwipeGestureRecognizer * swipe2 =[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeClick:)]; //向左扫动手势
swipe2.direction= UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipe2];
} -(void)swipeClick:(UISwipeGestureRecognizer *)swipe
{ if (swipe.direction==UISwipeGestureRecognizerDirectionRight) {
[UIView animateWithDuration:0.3 animations:^{ self.headerView.transform = CGAffineTransformTranslate(self.headerView.transform, , ); }completion:^(BOOL finished) { [UIView animateWithDuration:0.5 animations:^{
self.headerView.transform = CGAffineTransformIdentity; }]; }]; }
else if (swipe.direction==UISwipeGestureRecognizerDirectionLeft) { [UIView animateWithDuration:0.3 animations:^{ self.headerView.transform = CGAffineTransformTranslate(self.headerView.transform, -, ); }completion:^(BOOL finished) { [UIView animateWithDuration:0.5 animations:^{
self.headerView.transform = CGAffineTransformIdentity; }];
}];
}
} #pragma mark - 拖拽手势
- (IBAction)panBtnClick { UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panClick:)]; [self.view addGestureRecognizer:pan]; } -(void)panClick:(UIPanGestureRecognizer *)pan
{
CGPoint point = [pan translationInView:self.view]; self.headerView.transform = CGAffineTransformTranslate(self.headerView.transform, point.x, point.y); [pan setTranslation:CGPointZero inView:self.view];
} //手势识别代理实现
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES; }

四、补充

1、同一个控件添加多个手势,触发冲突的问题,比如双击和单击。

(1)问题描述

  手势是可以互相关联的,例如 Tap 与 LongPress、Swipe与 Pan,或是 Tap 一次与Tap 两次。当一个 UIView 同时添加两个相关联的手势时,到底我这一下手指头按的要算是 Tap 还是 LongPress?如果照预设作法来看,只要「先满足条件」的就会跳出并呼叫对应方法,举例来说,如果同时注册了 Pan 和 Swipe,只要手指头一移动就会触发 Pan 然后跳出,因而永远都不会发生 Swipe;单点与双点的情形也是一样,永远都只会触发单点,不会有双点。

(2)解决方法:requireGestureRecognizerToFail --手势的对象方法

  指定某一个 recognizer,即便自己已经满足条件了,也不会立刻触发,会等到该指定的 recognizer 确定失败之后才触发。

(3)举例  

  //如果双击确定侦测失败才会触发单击

  [singleRecognizer requireGestureRecognizerToFail:doubleRecognizer];

iOS手势识别的更多相关文章

  1. iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势)

    iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势)       1.UIGestureRecognizer介绍 手势识别在iOS上非常重要,手势操作移动设备的重要特征,极大的增加 ...

  2. ios iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势)

    iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势) 转自容芳志大神的博客:http://www.cnblogs.com/stoic/archive/2013/02/27/2940 ...

  3. iOS,手势识别简单使用

    1.iOS目前支持的手势识别(6种) 2.点按手势和慢速拖动手势简单使用 iOS目前支持的手势识别(6种) UITapGestureRecognizer(点按) UIPinchGestureRecog ...

  4. UIGestureRecognizer ios手势识别温习

    1.UIGestureRecognizer介绍 手势识别在iOS上非常重要,手势操作移动设备的重要特征,极大的增加了移动设备使用便捷性. iOS系统在3.2以后,为方便开发这使用一些常用的手势,提供了 ...

  5. 【转】iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势) -- 不错不错

    原文网址:http://blog.csdn.net/totogo2010/article/details/8615940 1.UIGestureRecognizer介绍 手势识别在iOS上非常重要,手 ...

  6. 介绍一些实用的IOS手势识别库 (COCOS2D)

    http://www.supersuraccoon-cocos2d.com/zh/2012/11/14/introduction-to-some-great-ios-gesture-recogniti ...

  7. ios手势识别代理

    之前做优质派时写了个仿网易新闻导航的第三方,由于当时做项目时这个主控制器就是RootViewController,虽然用的是ScrollView但也没考虑到导航栏的手势返回的问题 ,现在做小区宝3.0 ...

  8. iOS 手势识别

    首先给大家解释一下为什么要学习手势识别? 如果想监听一个UIView上面的触摸事件,之前的做法是: 自定义一个UIView : 实现UIView的touches方法,在方法里面实现具体功能 透过tou ...

  9. IOS手势识别,捏合,旋转,轻扫等

    ref:http://blog.csdn.net/rechard_chen/article/details/51769972   //点按手势的创建,这里需要实现响应事件的方法 UITapGestur ...

随机推荐

  1. [文章转载]-我的Java后端书架-江南白衣

    我的Java后端书架 (2016年暮春3.0版) 04月 24, 2016 | Filed under 技术 书架主要针对Java后端开发. 3.0版把一些后来买的.看的书添补进来,又或删掉或降级一些 ...

  2. transactoin

    hibernate对数据的操作是封装在事务当中,并且默认是非自动提交方式.所以用session保存对象时,如果不开启事务,并且手工提交事务,对象并不会真正保存在数据库中.

  3. python实战教程之自动扫雷

    1.找到游戏窗口与坐标 #扫雷游戏窗口class_name = "TMain"title_name = "Minesweeper Arbiter "hwnd = ...

  4. display: table-cell; 自适应布局

    #extras {display: table-cell;width: 180px;padding-left: 10px;border-right: 1px dotted #d7ad7b;} tabl ...

  5. Linux之iptables(三、命令--->单主机)

    iptables命令规则格式: iptables [-t table] SUBCOMMAND chain [-m matchname[per-match-options]] -j targetname ...

  6. 第三节:Web爬虫之BeautifulSoup解析库

    Beautiful Soup官方说明: Beautiful Soup提供一些简单的.python式的函数用来处理导航.搜索.修改分析树等功能.它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为 ...

  7. protel99se 问题汇总(不定期更新)

    1.在PROTEL99SE中,怎样改变敷铜的线宽? 规则---manufacturing----polygon connect style 里面设置:或Power polygon connect st ...

  8. 【codeforces 509B】Painting Pebbles

    [题目链接]:http://codeforces.com/contest/509/problem/B [题意] 给n鹅卵石染色; 有k种颜色可供选择; 问你有没有染色方案; 使得各个堆的鹅卵石里面,第 ...

  9. Spring Boot-Starter(九)

    说明 在使用非spring boot项目我们集成spring mvc mybatis等框架往往需要大量xml配置, spring 的推出是为了解决项目的复杂度,随着项目的增长,xml配置会越来越臃肿, ...

  10. Python 6 数字和布尔值及字符串的基本功能

    数据类型:查看变量数据类型type(变量)  或者  print(type(变量)) 整数int:就是不带小数的自然数字,也叫整型.在2.X版本中还分为长整型和整形.但是在3.X版本中统一称为整数或整 ...