欢迎来到 IT实训基地-南通科迅教育
咨询电话:0513-81107100
iOS的手势识别器
2016/12/19
科迅教育
472
南通IT培训班有用吗

一. 监听触摸事件的做法

如果想监听一个view上面的触摸事件,不使用手势实现的步骤
(1). 自定义一个view
(2). 实现view的touches方法,在方法内部实现具体处理代码

通过touches方法监听view触摸事件,有很明显的几个缺点
(1). 必须得自定义view
(2). 由于是在view内部的touches方法中监听触摸事件,因此默认情况下,无法让其他外界对象监听view的触摸事件
(3). 不容易区分用户的具体手势行为

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

二. 手势识别器简介

为了完成手势识别,必须借助于手势识别器:UIGestureRecognizer

利用UIGestureRecognizer,能轻松识别用户在某个view上面做的一些常见手势

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

UIGestureRecognizer的子类

UITapGestureRecognizer(敲击)
UIPinchGestureRecognizer(捏合,用于缩放)
UIPanGestureRecognizer(拖拽)
UISwipeGestureRecognizer(轻扫)
UIRotationGestureRecognizer(旋转)
UILongPressGestureRecognizer(长按)

三. UIGestureRecognizer的常见属性和方法

UIGestureRecognizer继承于NSObject

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 初始化手势要触发的对象与事件
- (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action
// 添加手势要触发的对象与事件
- (void)addTarget:(id)target action:(SEL)action;
// 移除手势要触发的对象与事件
- (void)removeTarget:(nullable id)target action:(nullable SEL)action;
// 手势状态
@property(nonatomic,readonly) UIGestureRecognizerState state;
// 代理
@property(nullable,nonatomic,weak) iddelegate;
// 手势是否可用,默认YES
@property(nonatomic, getter=isEnabled) BOOL enabled;
// 只读,手势所属的视图
@property(nullable, nonatomic,readonly) UIView *view;
// 默认YES.意思就是说一旦手势被识别,那么就调用[touchView touchesCancelled:withEvent]
@property(nonatomic) BOOL cancelsTouchesInView;
// 默认NO.意思就是再手势识别成功之前,touchObj还是要分发到touchView.
// 设置为YES的时候就表示从手势识别成功之前touchObj不给touchView分发
@property(nonatomic) BOOL delaysTouchesBegan;
// 默认YES:在手势识别成功之前,touchesEnded不会被调用。
// 设置为NO:在手势识别成功之前,touchesEnded会被调用
@property(nonatomic) BOOL delaysTouchesEnded;
// 当指定的识别器(调用者)识别失败,才去识别另一个识别器otherGestureRecognizer
- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;
// 获取手势识别器的触摸点
- (CGPoint)locationInView:(nullable UIView*)view;
// 获取手势识别器的触摸点个数
- (NSUInteger)numberOfTouches;
// 指定触摸点的位置
- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view;

四. UIGestureRecognizer代理

注意: 使用多个手势必须使用代理

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 是否允许触发手势
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
// 是否允许多个同时支持多个手势,默认不允许,手势必须要设置代理
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
// 这个方法在这两个gesture recognizers中的任意一个将堵塞另一个的触摸事件时调用,
// 如果返回YES,则两个gesture recognizers可同时识别,
// 如果返回NO,则并不保证两个gesture recognizers必不能同时识别,
// 因为另外一个gesture recognizer的此方法可能返回YES。
// 也就是说两个gesture recognizers的delegate方法只要任意一个返回YES,则这两个就可以同时识别;
// 只有两个都返回NO的时候,才是互斥的。默认情况下是返回NO
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
// 是否允许手势识别器识别失败的时候使用另一个识别器otherGestureRecognizer
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
// 是否允许接收触摸点
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
// 是否允许接收长按点
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press;

五. UIGestureRecognizer的子类常见属性和方法

1. UITapGestureRecognizer(敲击)

?
1
2
3
4
// 需要连续敲击几次才可触发,默认1次
@property(nonatomic) NSUInteger numberOfTapsRequired;
// 需要几根手指一起敲击才可触发,默认1根
@property(nonatomic) NSUInteger numberOfTouchesRequired __TVOS_PROHIBITED;

2. UIPinchGestureRecognizer(捏合,用于缩放)

提示: 模拟器快捷键:opsin + shift 向上拖“两个触摸点”

?
1
2
3
4
// 缩放比例
@property(nonatomic) CGFloat scale;
// 缩放速度
@property(nonatomic,readonly) CGFloat velocity;

3. UIPanGestureRecognizer(拖拽)

?
1
2
3
4
5
6
7
8
9
10
// 拖动的最短距离
@property(nonatomic) NSUInteger minimumNumberOfTouches __TVOS_PROHIBITED;
// 拖动的最长距离
@property(nonatomic) NSUInteger maximumNumberOfTouches __TVOS_PROHIBITED;
// 在指定的view上得坐标
- (CGPoint)translationInView:(nullable UIView *)view;
// 设置在view中移动以后的坐标为translation
- (void)setTranslation:(CGPoint)translation inView:(nullable UIView *)view;
// 拖动view,返回的值就用于计算view相对于父控件拖动的速度
- (CGPoint)velocityInView:(nullable UIView *)view;

4. UISwipeGestureRecognizer(轻扫)

?
1
2
3
4
// 需要几根手指一起轻扫才可触发,默认1根
@property(nonatomic) NSUInteger numberOfTouchesRequired __TVOS_PROHIBITED;
// 设置轻扫方向
@property(nonatomic) UISwipeGestureRecognizerDirection direction;

5. UIRotationGestureRecognizer(旋转)

?
1
2
3
4
// 旋转角度
@property(nonatomic) CGFloat rotation;
// 旋转速度
@property(nonatomic,readonly) CGFloat velocity;

6. UILongPressGestureRecognizer(长按)

注意: 长安手势一般会触发两次,所有一般为了只做一次,要做一次判断

?
1
2
3
4
5
6
7
8
// 需要连续长按几次才可触发,默认0次
@property(nonatomic) NSUInteger numberOfTapsRequired;
// 需要几根手指一起长按才可触发,默认1根
@property(nonatomic) NSUInteger numberOfTouchesRequired __TVOS_PROHIBITED;
// 最小长按时间
@property(nonatomic) CFTimeInterval minimumPressDuration;
// 允许移动距离
@property(nonatomic) CGFloat allowableMovement;

六. 手势的具体使用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
 
#import"ViewController.h"
@interfaceViewController ()
@property(weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementationViewController
- (void)viewDidLoad {
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self setUpTap];
[self setUpLongPress];
[self setUpSwipe];
[self setUpRotation];
[self setUpPinch];
[self setUpPan];
}
#pragma mark - 点按手势
- (void)setUpTap {
UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(actionUpTap)];
// 多个手势必须要代理
gestureRecognizer.delegate = self;
[_imageView addGestureRecognizer:gestureRecognizer];
}
- (void)actionUpTap {
NSLog(@"点按手势");
}
#pragma mark - 长按手势
- (void)setUpLongPress {
UILongPressGestureRecognizer *gestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(actionLongPress)];
gestureRecognizer.delegate = self;
[_imageView addGestureRecognizer:gestureRecognizer];
}
- (void)actionLongPress {
NSLog(@"长按手势");
}
#pragma mark - 轻扫手势
- (void)setUpSwipe{
// 默认向右轻扫,如果要同时有多个轻扫方向,必须要创建轻扫对象
UISwipeGestureRecognizer *gestureRecognizerRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(actionSwipe)];
[_imageView addGestureRecognizer:gestureRecognizerRight];
UISwipeGestureRecognizer *gestureRecognizerLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(actionSwipe)];
// 向左轻扫
gestureRecognizerLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[_imageView addGestureRecognizer:gestureRecognizerLeft];
UISwipeGestureRecognizer *gestureRecognizerUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(actionSwipe)];
// 向上轻扫
gestureRecognizerUp.direction = UISwipeGestureRecognizerDirectionUp;
[_imageView addGestureRecognizer:gestureRecognizerUp];
UISwipeGestureRecognizer *gestureRecognizerDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(actionSwipe)];
// 向下轻扫
gestureRecognizerDown.direction = UISwipeGestureRecognizerDirectionDown;
[_imageView addGestureRecognizer:gestureRecognizerDown];
}
- (void)actionSwipe {
NSLog(@"轻扫手势");
}
#pragma mark - 旋转手势
- (void)setUpRotation {
UIRotationGestureRecognizer *gestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(actionRotation:)];
gestureRecognizer.delegate = self;
[_imageView addGestureRecognizer:gestureRecognizer];
}
- (void)actionRotation:(UIRotationGestureRecognizer *)rotation {
_imageView.transform = CGAffineTransformRotate(_imageView.transform, rotation.rotation);
// 复位
rotation.rotation =0;
}
#pragma mark - 捏合手势
- (void) setUpPinch {
UIPinchGestureRecognizer *gestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(actionPinch:)];
gestureRecognizer.delegate = self;
[_imageView addGestureRecognizer:gestureRecognizer];
}
- (void)actionPinch:(UIPinchGestureRecognizer *)pinch {
_imageView.transform = CGAffineTransformScale(_imageView.transform, pinch.scale, pinch.scale);
// 复位
pinch.scale =1;
}
#pragma mark - 拖拽手势
- (void)setUpPan {
UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(actionPan:)];
gestureRecognizer.delegate = self;
[_imageView addGestureRecognizer:gestureRecognizer];
}
- (void)actionPan:(UIPanGestureRecognizer *)pan {
//NSLog(@"%ld",[pan numberOfTouches]);
// 获取手势的触摸点
// CGPoint curP = [pan locationInView:self.imageView];
CGPoint panTrans = [pan translationInView:_imageView];
_imageView.transform = CGAffineTransformTranslate(_imageView.transform, panTrans.x, panTrans.y);
// 复位
[pan setTranslation:CGPointZero inView:_imageView];
}
#pragma mark - 手势代理
// 是否允许多个同时支持多个手势,默认不允许,手势必须要设置代理
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
returnYES;
}
// 是否允许触发手势事件
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
returnYES;
}
// 是否允许接收触摸点
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
returnYES;
}
@end
77
关闭
先学习,后交费申请表
每期5位名额
在线咨询
免费电话
QQ联系
先学习,后交费
TOP
您好,您想咨询哪门课程呢?
关于我们
机构简介
官方资讯
地理位置
联系我们
0513-91107100
周一至周六     8:30-21:00
微信扫我送教程
手机端访问
南通科迅教育信息咨询有限公司     苏ICP备15009282号     联系地址:江苏省南通市人民中路23-6号新亚大厦三楼             法律顾问:江苏瑞慈律师事务所     Copyright 2008-