触摸事件与手势识别

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

触摸事件与⼿势识别
UIView是UIResponder的⼦类,可以覆盖下列4个⽅法处理不同的触摸事件。

[objc]
1. 1. ⼀根或者多根⼿指开始触摸屏幕
2. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
3. 2.⼀根或者多根⼿指在屏幕上移动(随着⼿指的移动,会持续调⽤该⽅法)
4. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
5. 3.⼀根或者多根⼿指离开屏幕
6. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
7. 4.触摸结束前,某个系统事件(例如电话呼⼊)会打断触摸过程
8. - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
9. 注意:所有UIKit控件均继承⾃UIView
常⽤属性:
[objc]
1. 1.UITouch *touch = [touches anyObject];//1. 从NSSet中取出UITouch对象
2. 2.CGPoint location = [touch locationInView:self.view];//// 2. ⼿指触摸的位置
3. 3.[touch previousLocationInView:]⽅法对位置进⾏修正
4. 4.touches.count来判断是多点还是单点触摸
5. 5. [self.view setMultipleTouchEnabled:YES]设置为yes ⽀持多点触摸
6. 6.CGPoint greenPoint = [selfconvertPoint:point toView:self.greenView];//将point有点击的试图转到greenView上,返回此点在greenView上到坐标
7. 7.[self.greenViewpointInside:greenPoint withEvent:event]判断greenPoint是否在greenView上
8. 8.[touch view] 获取但前触摸到试图
[objc]
1. #pragma mark 触摸移动 -在⼀次触摸事件中,可能会被调⽤多次
2. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
3. {
4. // 1. 从NSSet中取出UITouch对象
5. UITouch *touch = [touchesanyObject];
6. // 2. 知道⼿指触摸的位置
7. CGPoint location = [touchlocationInView:self.view];
8. // 2.1 可以利⽤[touch previousLocationInView:]⽅法对位置进⾏修正
9. CGPoint pLocation = [touchpreviousLocationInView:self.view];
10. CGPoint deltaP =CGPointMake(location.x - pLocation.x, location.y - pLocation.y);
11. CGPoint newCenter =CGPointMake(self.redView.center.x + deltaP.x, self.redView.center.y + deltaP.y);
12.
13. // 3. 设置红⾊视图的位置
14. [self.redViewsetCenter:newCenter];
15. }
多点触摸:
在iOS中,视图默认不⽀持多点触摸,通常在使⽤UITouch开发时,为了避免不必要的⿇烦,也最好不要⽀持多点
需要⽀持多点必须把 [self.viewsetMultipleTouchEnabled:YES]设置为yes
[objc]
1. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
2. {
3. //可以通过touches.count来判断是多点还是单点触摸
4. // 遍历touches集合来添加图像
5. NSInteger i =0;
6. for (UITouch *touchin touches) {
7. UIImageView *imageView = [[UIImageViewalloc]initWithImage:self.images[i]];
8. CGPoint location = [touchlocationInView:self.view];//⼿指触摸的位置
9. [imageView setCenter:location];
10. [self.viewaddSubview:imageView];
11. [UIViewanimateWithDuration:2.0fanimations:^{
12. [imageView setAlpha:0.5f];
13. } completion:^(BOOL finished) {
14. [imageView removeFromSuperview];
15. }];
16.
17. i++;
18. }
19. }
摇晃事件:
摇晃的试图必须重写此⽅法,并返回yes
[objc]
1. - (BOOL)canBecomeFirstResponder
2. {
3. returnYES;
4. }
5. #pragma mark - 监听运动事件
6. - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
7. {
8. if (UIEventSubtypeMotionShake == motion) {
9. NSLog(@"摇晃啦");
10. // 摇晃的后续处理
11. //
12. // 1. 记录⽤户当前位置(经纬度)
13. // 2. 去服务器上查询当前摇晃⼿机的⽤户记录
14. // 3. 根据⽤户所在经纬度,取出前N名距离⽤户最近的⽤户记录
15. // 4. 将⽤户记录发送到⽤户⼿机
16. // 5. ⼿机接收到数据后,self.tableView reloadData
17. }
18. }
19. [objc]
1. // 1. 点按⼿势
2. UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
3. // 点按次数,例如双击2
4. // 注意:在iOS中最好少⽤双击,如果⼀定要⽤,就⼀定要有⼀个图形化的界⾯告知⽤户可以双击
5. [tap setNumberOfTapsRequired:2];
6. // ⽤⼏根⼿指点按
7. [tap setNumberOfTouchesRequired:1];
8. [imageView addGestureRecognizer:tap];
9.
10. // 2. 长按⼿势 Long Press
11. UILongPressGestureRecognizer *longTap = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longTap:)];
12. [imageView addGestureRecognizer:longTap];
13.
14. // 3. 拖动⼿势 Pan
15. UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];
16. [imageView addGestureRecognizer:pan];
17.
18. // 4. 旋转⼿势 Rotation
19. UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotation:)];
20. [imageView addGestureRecognizer:rotation];
21.
22. // 5. 缩放(捏合)⼿势 Pinch
23. UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinch:)];
24. [imageView addGestureRecognizer:pinch];
25.
26. // 6. 轻扫⼿势 Swipe
27. /*
28. ⼿指在屏幕上扫动,和拖动⼿势的区别在于,⼿指离开屏幕才会触发监听⽅法
29.
30. 1> ⼿指可以上、下、左、右四个⽅向轻轻扫动,如果没有指定⽅向,默认都是向右扫动
31. 2> 在设置轻扫⼿势时,通常需要将⼿势识别添加到⽗视图上监听
32. 3> 在监听⽅法中,注意不要使⽤recognizaer.view,因为⼿势监听的是⽗视图,⽽要处理的视图通常是其他的视图
33.
34. 如果要使⽤多个⽅向的轻扫⼿势,需要指定多个轻扫⼿势,通常只需指定左右两个⽅向即可。

35.
36. 因为iOS⽤户⼤多不习惯上下的轻扫动作
37. */
38. UISwipeGestureRecognizer *swipe1 = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
39. [swipe1 setDirection:UISwipeGestureRecognizerDirectionUp];
40. [self.view addGestureRecognizer:swipe1];
41.
42. UISwipeGestureRecognizer *swipe2 = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
43. [swipe2 setDirection:UISwipeGestureRecognizerDirectionDown];
44. [self.view addGestureRecognizer:swipe2];
45.
46. UISwipeGestureRecognizer *swipe3 = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
47. [swipe3 setDirection:UISwipeGestureRecognizerDirectionLeft];
48. [self.view addGestureRecognizer:swipe3];
49.
50. UISwipeGestureRecognizer *swipe4 = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipe:)];
51. [swipe4 setDirection:UISwipeGestureRecognizerDirectionRight];
52. [self.view addGestureRecognizer:swipe4];
[objc]
1. #pragma mark - ⼿势监听⽅法
2. #pragma mark 轻扫⼿势
3. // 尽管轻扫⼿势也是连续⼿势,但是该⼿势是在⼿指离开屏幕才会被触发的
4. // 因此,在编写代码时,不需要处理⼿势的状态
5. - (void)swipe:(UISwipeGestureRecognizer *)recognizer
6. {
7. // 让图⽚朝⼿指不同的⽅向飞出屏幕,然后再复位
8. CGRect frame = kImageInitFrame;
9. if (UISwipeGestureRecognizerDirectionUp == recognizer.direction) {
10. frame.origin.y -= 400;
11. } else if (UISwipeGestureRecognizerDirectionDown == recognizer.direction) {
12. frame.origin.y += 400;
13. } else if (UISwipeGestureRecognizerDirectionLeft == recognizer.direction) {
14. frame.origin.x -= 300;
15. } else {
16. frame.origin.x += 300;
17. }
18.
19. [UIView animateWithDuration:1.0 animations:^{
20. [self.imageView setFrame:frame];
21. } completion:^(BOOL finished) {
22. [UIView animateWithDuration:1.0f animations:^{
23. [self.imageView setFrame:kImageInitFrame];
24. }];
25. }];
26. }
27.
28. #pragma mark 捏合⼿势
29. - (void)pinch:(UIPinchGestureRecognizer *)recognizer
30. {
31. /**
32. 变化过程中,放⼤缩⼩
33. 结束后,恢复
34. */
35. if (UIGestureRecognizerStateChanged == recognizer.state) {
36. [recognizer.view setTransform:CGAffineTransformMakeScale(recognizer.scale, recognizer.scale)];
37.
38. } else if (UIGestureRecognizerStateEnded == recognizer.state) {
39. [UIView animateWithDuration:0.5f animations:^{
40. // 恢复初始位置,清除所有的形变效果
41. [recognizer.view setTransform:CGAffineTransformIdentity];
42. }];
43. }
44.
45. }
46.
47. #pragma mark 旋转⼿势,⾄少两根⼿指
48. - (void)rotation:(UIRotationGestureRecognizer *)recognizer
49. {
50. // recognizer中的rotation属性是基于图⽚的初始旋转弧度的
51. /**
52. 变化过程中,旋转
53. 结束后,恢复
54. */
55. if (UIGestureRecognizerStateChanged == recognizer.state) {
56. [recognizer.view setTransform:CGAffineTransformMakeRotation(recognizer.rotation)];
57. /**
58. 累加的形变
59. */
60. // [recognizer.view setTransform:CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation)];
61. // // 把⼿势识别的rotation设置为0,在下⼀次触发时,以当前的旋转⾓度为基准继续旋转
62. // recognizer.rotation = 0;
63. } else if (UIGestureRecognizerStateEnded == recognizer.state) {
64. [UIView animateWithDuration:0.5f animations:^{
65. // 恢复初始位置,清除所有的形变效果
66. [recognizer.view setTransform:CGAffineTransformIdentity];
67. }];
68. }
69. }
70.
71. #pragma mark 拖动⼿势
72. - (void)pan:(UIPanGestureRecognizer *)recognizer
73. {
74. NSLog(@"拖动");
75.
76. /*
77. 拖动⼿势结束后,以动画的⽅式回到初始位置
78. */
79. // 在⼿势状态处于“变化”时处理图⽚的移动
80. // UIGestureRecognizerStateChanged类似于touchesMoved⽅法,会不断地被调⽤
81. if (UIGestureRecognizerStateChanged == recognizer.state) {
82.
83. // translationInView,判断在⽗视图中平移的位置,平移的偏移量始终以视图的初始位置为基础
84. CGPoint deltaPoint = [recognizer translationInView:self.view];
85.
86. // ⽤形变参数来改变图像的位置
87. [recognizer.view setTransform:CGAffineTransformMakeTranslation(deltaPoint.x, deltaPoint.y)];
88.
89. // CGRect targetRect = kImageInitFrame;
90. // targetRect.origin.x += deltaPoint.x;
91. // targetRect.origin.y += deltaPoint.y;
92. //
93. // [recognizer.view setFrame:targetRect];
94. } else if (UIGestureRecognizerStateEnded == recognizer.state) {
95. [UIView animateWithDuration:0.5f animations:^{
96. // 将图⽚复位
97. // [recognizer.view setFrame:kImageInitFrame];
98. [recognizer.view setTransform:CGAffineTransformIdentity];
99. }];
100. }
101. }
102.
103. #pragma mark 长按⼿势
104. - (void)longTap:(UILongPressGestureRecognizer *)recognizer
105. {
106. NSLog(@"长按");
107. /*
108. 旋转半圈的动画,动画完成后恢复
109.
110. 长按⼿势属于连续⼿势,是需要处理状态
111.
112. 因为长按通常只有⼀根⼿指,因此在Began状态下,长按⼿势就已经被识别了113.
114. 针对长按的处理,最好放在UIGestureRecognizerStateBegan状态中实现115. */
116. if (UIGestureRecognizerStateBegan == recognizer.state) {
117. NSLog(@"长按");
118.
119. [UIView animateWithDuration:1.0f animations:^{
120. [recognizer.view setTransform:CGAffineTransformMakeRotation(M_PI)]; 121. } completion:^(BOOL finished) {
122. // CGAffineTransformIdentity将视图的形变复原(平移、缩放、旋转)123. [recognizer.view setTransform:CGAffineTransformIdentity];
124. }];
125. } else if (UIGestureRecognizerStateEnded == recognizer.state) {
126. // [UIView animateWithDuration:1.0f animations:^{
127. // [recognizer.view setTransform:CGAffineTransformMakeRotation(M_PI)]; 128. // } completion:^(BOOL finished) {
129. // // CGAffineTransformIdentity将视图的形变复原(平移、缩放、旋转)130. // [recognizer.view setTransform:CGAffineTransformIdentity];
131. // }];
132. }
133. }
134.
135. #pragma mark 点按⼿势
136. - (void)tap:(UITapGestureRecognizer *)recognizer
137. {
138. NSLog(@"点我了");
139. // 做⼀个动画效果
140. // 向下移出屏幕,完成后再重新返回初始位置
141. // recognizer.view 就是识别到⼿势的视图,也就是⼿势绑定到得视图
142.
143. CGRect initFrame = recognizer.view.frame;
144. CGRect targetFrame = recognizer.view.frame;
145. targetFrame.origin.y += 360;
146.
147. [UIView animateWithDuration:1.0f animations:^{
148. // ⾃动反向重复动画
149. [UIView setAnimationRepeatAutoreverses:YES];
150. // 设置动画重复次数
151. [UIView setAnimationRepeatCount:2];
152.
153. [recognizer.view setFrame:targetFrame];
154. } completion:^(BOOL finished) {
155. [recognizer.view setFrame:initFrame];
156. }];
157. }。

相关文档
最新文档