手势识别

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

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

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

UIGestureRecognizer(抽象类)

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

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

UITapGestureRecognizer(敲击)

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
- (void)setUpTap
{
// 创建点按手势 会把手势对象作为参数传到方法中去
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];

// numberOfTapsRequired (需要点几次触发手势)

// 设置手势代理
tap.delegate = self;

// 添加手势
[self.imageView addGestureRecognizer:tap];
}

- (void)pan:(UIPanGestureRecognizer *)pan
{
// 获取手势的触摸点
CGPoint curP = [pan locationInView:self.imageView];

// 移动视图
// 获取手势的移动,也是相对于最开始的位置
CGPoint transP = [pan translationInView:self.imageView];

self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, transP.x, transP.y);

// 复位
[pan setTranslation:CGPointZero inView:self.imageView];

NSLog(@"%@",NSStringFromCGPoint(curP));
}

手势代理方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 是否允许开始触发手势
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
return NO;
}

// 是否允许同时支持多个手势,默认是不支持多个手势
// 返回yes表示支持多个手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}

// 是否允许接收手指的触摸点
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
// 获取当前的触摸点
CGPoint curP = [touch locationInView:self.imageView];

if (curP.x < self.imageView.bounds.size.width * 0.5) {
return NO;
}else{
return YES;
}
}

UILongPressGestureRecognizer(长按)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 默认会触发两次
- (void)setUpLongPress
{
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];

[self.imageView addGestureRecognizer:longPress];
}

// 开始长按时会调用一次,长按结束时会调用一次
- (void)longPress:(UILongPressGestureRecognizer *)longPress
{

if (longPress.state == UIGestureRecognizerStateBegan) { // 长按开始时

NSLog(@"%s",__func__);
}
}

UISwipeGestureRecognizer(轻扫)

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
// 默认轻扫的方向是往右
UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe)];

/* 设置手势方向,

typedef NS_OPTIONS(NSUInteger, UISwipeGestureRecognizerDirection) {
UISwipeGestureRecognizerDirectionRight = 1 << 0, 默认时往右
UISwipeGestureRecognizerDirectionLeft = 1 << 1, 往左
UISwipeGestureRecognizerDirectionUp = 1 << 2, 上
UISwipeGestureRecognizerDirectionDown = 1 << 3 下
};
*/

swipe.direction = UISwipeGestureRecognizerDirectionUp;

[self.imageView addGestureRecognizer:swipe];

// 如果以后想要一个控件支持多个方向的轻扫,必须创建多个轻扫手势,一个轻扫手势只支持一个方向
// 默认轻扫的方向是往右
UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipe)];

swipeDown.direction = UISwipeGestureRecognizerDirectionDown;

[self.imageView addGestureRecognizer:swipeDown];

- (void)swipe
{
NSLog(@"%s",__func__);
}

UIRotationGestureRecognizer(旋转)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- (void)setUpRotation
{
UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotation:)];
rotation.delegate = self;
[self.imageView addGestureRecognizer:rotation];
}

// 默认传递的旋转的角度都是相对于最开始的位置
- (void)rotation:(UIRotationGestureRecognizer *)rotation
{
// 获取手势旋转的角度
NSLog(@"%f",rotation.rotation);

self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, rotation.rotation);

// 复位 :相当于上一次最后的状态 当做下一次初始状态进行操作
rotation.rotation = 0;

}

UIPinchGestureRecognizer(捏合)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- (void)setUpPinch
{
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinch:)];
pinch.delegate = self;
[self.imageView addGestureRecognizer:pinch];
}

- (void)pinch:(UIPinchGestureRecognizer *)pinch
{
self.imageView.transform = CGAffineTransformScale(self.imageView.transform, pinch.scale, pinch.scale);

// 复位

pinch.scale = 1;
}

UIPanGestureRecognizer(拖拽)

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

- (void)setUpPan
{
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(pan:)];


[self.imageView addGestureRecognizer:pan];
}

- (void)pan:(UIPanGestureRecognizer *)pan
{
// 获取手势的触摸点
CGPoint curP = [pan locationInView:self.imageView];

// 移动视图
// 获取手势的移动,也是相对于最开始的位置
CGPoint transP = [pan translationInView:self.imageView];

self.imageView.transform = CGAffineTransformTranslate(self.imageView.transform, transP.x, transP.y);

// 复位
[pan setTranslation:CGPointZero inView:self.imageView];

NSLog(@"%@",NSStringFromCGPoint(curP));
}

练习:抽屉效果

代码:抽屉效果

文章作者: Ammar
文章链接: http://lizhaoloveit.cn/2014/07/09/%E6%89%8B%E5%8A%BF%E8%AF%86%E5%88%AB/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ammar's Blog
打赏
  • 微信
  • 支付宝

评论