iOS 手势UIGestureRecognizer
在 iPhone 或 iPad 的开发中,除了用 touchesBegan / touchesMoved / touchesEnded 这组方法来控制使用者的手指触控外,也可以用 UIGestureRecognizer 的衍生类別来进行判断。用 UIGestureRecognizer 的好处在于有现成的手势,开发者不用自己计算手指移动轨迹。UIGestureRecognizer的衍生类別有以下几种:
UITapGestureRecognizer
UIPinchGestureRecognizer
UIRotationGestureRecognizer
UISwipeGestureRecognizer
UIPanGestureRecognizer
UILongPressGestureRecognizer
从命名上不难了解這些类別所对应代表的手势,分別是 Tap(点一下)、Pinch(二指往內或往外拨动)、Rotation(旋转)、Swipe(滑动,快速移动)、Pan (拖移,慢速移动)以及 LongPress(长按)。這些手势別在使用上也很简单,只要在使用前定义并添加到对应的视图上即可。
复制代码
// 定义一个 recognizer, 并加到需要偵測该手势的 UIView 元件上
- (void)viewDidLoad {
UISwipeGestureRecognizer* recognizer;
// handleSwipeFrom 是偵測到手势,所要呼叫的方法
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleSwipeFrom)];
// 不同的 Recognizer 有不同的实体变数
// 例如 SwipeGesture 可以指定方向
// 而 TapGesture 則可以指定次數
recognizer.direction = UISwipeGestureRecognizerDirectionUp
[self.view addGestureRecognizer:recognizer];
[recognizer release];
}
- (void)handleSwipeFrom:(UISwipeGestureRecognizer*)recognizer {
// 触发手勢事件后,在这里作些事情
// 底下是刪除手势的方法
[self.view removeGestureRecognizer:recognizer];
}
复制代码
问题來了。有些手势其实是互相关联的,例如 Tap 与 LongPress、Swipe与 Pan,或是 Tap 一次与Tap 兩次。当一個 UIView 同时添加兩个相关联的手势时,到底我这一下手指头按的要算是 Tap 还是 LongPress?如果照預设作法来看,只要「先滿足条件」的就会跳出并呼叫对应方法,举例来说,如果同时注册了 Pan 和 Swipe,只要手指头一移动就会触发 Pan 然后跳出,因而永远都不會发生 Swipe;单点与双点的情形也是一样,永远都只会触发单点,不會有双点。
那么这个问题有解吗?答案是肯定的,UIGestureRecognizer 有个方法叫做requireGestureRecognizerToFail,他可以指定某一个 recognizer,即便自己已经滿足條件了,也不會立刻触发,会等到该指定的 recognizer 确定失败之后才触发。以同时支持单点与双点的手势为例,代码如下:
复制代码
- (void)viewDidLoad {
// 单击的 Recognizer
UITapGestureRecognizer* singleRecognizer;
singleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleSingleTapFrom)];
singleTapRecognizer.numberOfTapsRequired = 1; // 单击
[self.view addGestureRecognizer:singleRecognizer];
// 双击的 Recognizer
UITapGestureRecognizer* double;
doubleRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:selfaction:@selector(handleDoubleTapFrom)];
doubleTapRecognizer.numberOfTapsRequired = 2; // 双击
[self.view addGestureRecognizer:doubleRecognizer];
// 关键在这一行,如果双击确定偵測失败才會触发单击
[singleRecognizer requireGestureRecognizerToFail:doubleRecognizer];
[singleRecognizer release];
[doubleRecognizer release];
}
Demo
首先新建一个基于Sigle view Application的项目,名为GestureTest;我的项目结构如下:
往viewController.xib文件里拖动一个imageView,并使覆盖整个屏幕,改动属性为:
viewController.h文件:
1. #import <UIKit/UIKit.h>
2.
3. @interface ViewController : UIViewController{
4. IBOutlet UIImageView *imageView;
5. }
6. @property (nonatomic,retain)IBOutlet UIImageView *imageView;
7. @end
并使xib文件里的imageView与之连接;
然后是viewController.m文件的实现部分:
1. @synthesize imageView;
2.
3. CGFloat lastScaleFactor=1;//放大、缩小
4. CGFloat netRotation;//旋转
5. CGPoint netTranslation;//平衡
6. NSArray *images;//图片数组
7. int imageIndex=0;//数组下标
8.
9. - (void)viewDidLoad
10. {
11. //1、创建手势实例,并连接方法handleTapGesture,点击手势
12. UITapGestureRecognizer *tapGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handleTapGesture:)];
13. //设置手势点击数,双击:点2下
14. tapGesture.numberOfTapsRequired=2;
15. // imageView添加手势识别
16. [imageView addGestureRecognizer:tapGesture];
17. //释放内存
18. [tapGesture release];
19.
20. //2、手势为捏的姿势:按住option按钮配合鼠标来做这个动作在虚拟器上
21. UIPinchGestureRecognizer *pinchGesture=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinchGesture:)];
22. [imageView addGestureRecognizer:pinchGesture];//imageView添加手势识别
23. [pinchGesture release];
24.
25. //3、旋转手势:按住option按钮配合鼠标来做这个动作在虚拟器上
26. UIRotationGestureRecognizer *rotateGesture=[[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(handleRotateGesture:)];
27. [imageView addGestureRecognizer:rotateGesture];
28. [rotateGesture release];
29.
30. //4、拖手势
31. UIPanGestureRecognizer *panGesture=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(handlePanGesture:)];
32. // [imageView addGestureRecognizer:panGesture];
33. [panGesture release];
34.
35. //5、划动手势
36. images=[[NSArray alloc]initWithObjects:@"cell.jpg",@"heihua.jpg",@"xuanyi.jpg", nil];
37. //右划
38. UISwipeGestureRecognizer *swipeGesture=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeGesture:)];
39. [imageView addGestureRecognizer:swipeGesture];
40. [swipeGesture release];
41. //左划
42. UISwipeGestureRecognizer *swipeLeftGesture=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeGesture:)];
43. swipeGesture.direction=UISwipeGestureRecognizerDirectionLeft;//不设置黑夜是右
44. [imageView addGestureRecognizer:swipeLeftGesture];
45. [swipeLeftGesture release];
46.
47. //6、长按手势
48. UILongPressGestureRecognizer *longpressGesutre=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleLongpressGesture:)];
49. //长按时间为1秒
50. longpressGesutre.minimumPressDuration=1;
51. //允许15秒中运动
52. longpressGesutre.allowableMovement=15;
53. //所需触摸1次
54. longpressGesutre.numberOfTouchesRequired=1;
55. [imageView addGestureRecognizer:longpressGesutre];
56. [longpressGesutre release];
57.
58. [super viewDidLoad];
59. // Do any additional setup after loading the view, typically from a nib.
60. }
61. //双击屏幕时会调用此方法,放大和缩小图片
62. -(IBAction)handleTapGesture:(UIGestureRecognizer*)sender{
63. //判断imageView的内容模式是否是UIViewContentModeScaleAspectFit,该模式是原比例,按照图片原时比例显示大小
64. if(sender.view.contentMode==UIViewContentModeScaleAspectFit){
65. //把imageView模式改成UIViewContentModeCenter,按照图片原先的大小显示中心的一部分在imageView
66. sender.view.contentMode=UIViewContentModeCenter;
67. }else{
68. sender.view.contentMode=UIViewContentModeScaleAspectFit;
69. }
70. }
71. //捏的手势,使图片放大和缩小,捏的动作是一个连续的动作
72. -(IBAction)handlePinchGesture:(UIGestureRecognizer*)sender{
73. //得到sender捏手势的大小
74. CGFloat factor=[(UIPinchGestureRecognizer*)sender scale];
75. if(factor>1){
76. //图片放大
77. sender.view.transform=CGAffineTransformMakeScale(lastScaleFactor+(factor-1), (lastScaleFactor+(factor-1)));
78.
79. }else{
80. //缩小
81. sender.view.transform=CGAffineTransformMakeScale(lastScaleFactor*factor, lastScaleFactor*factor);
82.
83. }
84. //状态是否结束,如果结束保存数据
85. if(sender.state==UIGestureRecognizerStateEnded){
86. if(factor>1){
87. lastScaleFactor+=(factor-1);
88. }else{
89. lastScaleFactor*=factor;
90. }
91. }
92. }
93. //旋转手势
94. -(IBAction)handleRotateGesture:(UIGestureRecognizer*)sender{
95. //浮点类型,得到sender的旋转度数
96. CGFloat rotation=[(UIRotationGestureRecognizer*)sender rotation];
97. //旋转角度CGAffineTransformMakeRotation
98. CGAffineTransform transform=CGAffineTransformMakeRotation(rotation+netRotation);
99. //改变图像角度
100. sender.view.transform=transform;
101. //状态结束,保存数据
102. if(sender.state==UIGestureRecognizerStateEnded){
103. netRotation+=rotation;
104. }
105.
106. }
107. //拖手势
108. -(IBAction)handlePanGesture:(UIGestureRecognizer*)sender{
109. //得到拖的过程中的xy坐标
110. CGPoint translation=[(UIPanGestureRecognizer*)sender translationInView:imageView];
111. //平移图片CGAffineTransformMakeTranslation
112. sender.view.transform=CGAffineTransformMakeTranslation(netTranslation.x+translation.x, netTranslation.y+translation.y);
113. //状态结束,保存数据
114. if(sender.state==UIGestureRecognizerStateEnded){
115. netTranslation.x+=translation.x;
116. netTranslation.y+=translation.y;
117. }
118.
119. }
120. //划动手势
121. -(IBAction)handleSwipeGesture:(UIGestureRecognizer*)sender{
122. //划动的方向
123. UISwipeGestureRecognizerDirection direction=[(UISwipeGestureRecognizer*) sender direction];
124. //判断是上下左右
125. switch (direction) {
126. case UISwipeGestureRecognizerDirectionUp:
127. NSLog(@"up");
128. break;
129. case UISwipeGestureRecognizerDirectionDown:
130. NSLog(@"down");
131. break;
132. case UISwipeGestureRecognizerDirectionLeft:
133. NSLog(@"left");
134. imageIndex++;//下标++
135. break;
136. case UISwipeGestureRecognizerDirectionRight:
137. NSLog(@"right");
138. imageIndex--;//下标--
139. break;
140. default:
141. break;
142. }
143. //得到不越界不<0的下标
144. imageIndex=(imageIndex<0)?([images count]-1):imageIndex%[images count];
145. //imageView显示图片
146. imageView.image=[UIImage imageNamed:[images objectAtIndex:imageIndex]];
147.
148. }
149. //长按手势
150. -(IBAction)handleLongpressGesture:(UIGestureRecognizer*)sender{
151. //创建警告
152. UIActionSheet *actionSheet=[[UIActionSheet alloc]initWithTitle:@"Image options" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:@"Save Image",@"Copy", nil];
153. //当前view显示警告
154. [actionSheet showInView:self.view];
155. [actionSheet release];
156. }
157. -(void)dealloc{
158. [images release];
159. [imageView release];
160. [super dealloc];
161. }
iOS 手势UIGestureRecognizer相关推荐
- iOS手势-UIGestureRecognizer
原文链接 1. UIGestureRecognizer 父类是NSObject 利用手势识别器---UIGestureRecognizer,能轻松识别用户在某个view上面做的一些常见手势 UIGes ...
- 使用iOS手势UIGestureRecognizer
UIKit中包含了UIGestureRecognizer类,用于检测发生在设备中的手势.UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,它有下面一些子类用于处理具体的手势 ...
- IOS手势 UIGestureRecognizer实践(Swift)
一 Tap轻点 // 双指轻点(需用真机测试)let doubleFingers = UITapGestureRecognizer(target: self, action: #selector(se ...
- IOS开发之手势——UIGestureRecognizer 共存
IOS开发之手势--UIGestureRecognizer 共存 在 iPhone 或 iPad 的开发中,除了用 touchesBegan / touchesMoved / touchesEnded ...
- iOS手势学习UIGestureRecognizer cocos2d 手势推荐
iOS手势学习UIGestureRecognizer & cocos2d 手势推荐 手势识别类型: UILongPressGestureRecognizer // 长按 UIPanGestu ...
- iOS手势操作简介(三)
监听触摸事件的做法 如果想监听一个view上面的触摸事件,之前的做法是 自定义一个view 实现view的touches方法,在方法内部实现具体处理代码 通过touches方法监听view触摸事件,有 ...
- iOS 手势的用法
iOS 手势类 : UIGestureRecognizer(继承于NSObject基类) 继承于UIGestureRecognizer类的有六个子类,分别是: UILongPressGestureRe ...
- swift 实现iOS手势密码、指纹密码、faceID
本博客包含了如何实现iOS手势密码.指纹密码.faceID全步骤,包括了完整的代码. 先附上demo地址https://github.com/Liuyubao/LYBTouchID,支持swift3. ...
- IOS开发之手势—UIGestureRecognizer 共存
在 iPhone 或 iPad 的开发中,除了用 touchesBegan / touchesMoved / touchesEnded 这组方法来控制使用者的手指触控外,也可以用 UIGestureR ...
最新文章
- #脱贫攻坚#彭蕾卸任蚂蚁金服后首次现身:女性脱贫亮三招
- windows msys编译64位x264和ffmpeg
- iOS总结:项目中的各种小坑汇总
- 一个端到端模型GraphDR实现多样化的召回
- 王者荣耀在线服务器,王者荣耀实时对战服务器Photon之PUN介绍
- JDK动态代理底层剖析
- java获取spring数据源_Spring动态注册多数据源的实现方法
- 有关数据库事务的一些理解-原生的Java的JDBC事务
- 计算机二级基础知识微盘,计算机二级C++基础知识(整理版).pdf
- 是几进制_10分钟带你了解什么是二进制
- pthread_cleanup_push()/pthread_cleanup_pop()的详解
- 2021全球国际化大学排名发布:中国大学居世界第一!
- 176.第二高的薪水
- 尝试修改smali码破解App
- Linux-常用命令
- TiDB EcoSystem Tools 原理解读(一):TiDB-Binlog 架构演进与实现原理
- 数据在云服务器中的安全性不会降低的原因
- [PHP] Larval 主从读写分离配置
- 叶蔬菜种子行业调研报告 - 市场现状分析与发展前景预测
- c语言求标准体重答案,c语言编写一个标准身高体重自测程序
热门文章
- JAVA软件海豚_海豚调度系统Apache DolphinScheduler单机部署官方文档(Standalone)
- 渗透测试-Kali虚拟机技术
- 图片转成pdf格式怎么转?三个好用的方法教给你
- 优维助力国内某省级商业银行同城异地灾备自动化建设
- 联筑赚赋能传统模架产业链数字化 促进产业发展互利共赢
- 若依框架内自带的excel导入导出功能
- bat for循环_bat教程[285] FOR/F options选项中usebackq的用法
- 【Unity实战100例】文件压缩Zip和ZIP文件的解压
- Android 实现自动点击屏幕的方法
- [linux虚拟机] 使用yum命令时,解析不了yum源,Cannot find a valid baseurl for repo: base/7/x86_6