文章目录
  1. 1. UIResponder传递路径
  2. 2. UIResponder触碰响应方法
  3. 3. 系统手势处理器(UIGestureRecognizer)
  4. 4. 手势冲突
  5. 5. 自定义手势
  6. 6. 参考

UIResponder传递路径

UIViewController和UIView都继承了UIResponder,因此他们及其子类都可以作为事件的响应者。事件响应者链的处理次序是: First Responder(用户触摸的view控件本身) -> First Responder的viewcontroller(如果有)-> 父View(如果有)->父View的viewcontroller(如果有)… ->UIWindow-> UIApplication->应用程序委托对象。(沿着nextResponder一路向上)

如果都没有处理,那么该事件被丢弃。如果某个响应者“截获”了某个事件,那么该响应者要依据条件决定是否处理该事件。当响应者无法处理该事件时,则需要再处理方法中手动传递该事件。如

1
2
3
4
5
6
7
- (void) handleTapEvent:(UIEvent*) event {
if (condition) {
// 处理事件
} else {
[self.nextResponder handleTapEvent:event];
}
}

UIResponder触碰响应方法

1
2
3
4
- touchBegan:(NSSet*)touches withEvent:(UIEvent*) event;
- touchMoved:(NSSet*)touches withEvent:(UIEvent*) event;
- touchEnded:(NSSet*)touches withEvent:(UIEvent*) event;
- touchCancelled:(NSSet*)touches withEvent:(UIEvent*) event;

可以通过重写UIResponder的如上四个方法来管理触碰的响应操作:

1
2
3
4
5
-(vid) touchBegan:(NSSet*)touches withEvent:(UIEvent*) event {
NSUInteger fingersNum = [touches count];
NSUInteger tapCount = [[touches anyObject] tapCount];
}

系统手势处理器(UIGestureRecognizer)

包括:

  • UITapGestureRecognizer 点击
  • UIPinchGestureRecognizer 捏合
  • UIRotationGestureRecognizer 旋转
  • UISwipGestureRecognizer 划动
  • UIPanGestureRecognizer 拖动
  • UILongPressGestureRecognizer 长按

使用步骤:

  1. 设置要添加手势控件如view的 userInteractionEnabled = YES;multipleTouchEnabled = YES; 属性;
  2. 给gestureRecognizer 添加target: action:,供发生手势时触发;
  3. 使用[view addGestureRecoginzer:]完成添加。

每个UIGestureRecoginzer包含如下属性和方法:

1
2
3
4
5
numberOfTouches: 用户的手指数
view : 激发该手势的view
state: 所处的状态,如UIGestureRecognizerStateBegan/Ended
-locationView:(UIView*) view: 返回该手势在view中的触碰位置
-locationForTouch:index inView: 返回该手势第index个触碰点在view中的触碰位置

此外, 各个处理还分别提供额外的属性来处理各自手势:

手势处理器 属性及说明

UIPinchGestureRecognizer | velocity 捏合的速度;scale 捏合的比例|
|UIRotationGestureRecogizer| rotation 旋转角度;velocity 速度|
|UISwipGestureRecognizer| direction 划动方向,如UISwipeGestureRecognizerDirectionRight/Left/Up/Down;numberOfTouchesRequired 指定只处理几个手指的触碰事件|
|UILongPressGestureRecognizer | minimumPressDuration 至少按的秒数;numberOfTouchesRequired 指定只处理几个手指的触碰事件;allowableMovement 允许移动手指的最大距离,超过则手势失效|

手势冲突

可以给每个UIGestureRecognizer设置一个实现UIGestureRecognizerDelegate的值,其包括了如下几个方法:

1
2
3
4
5
6
- gestureRecognizerShouldBegin: 在手势想要从UIGestureRecognizerStatePossible状态变化的时候调用,返回NO则表示手势状态是UIGestureRecognizerStateFailed
- gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer: 在手势冲突时候调用,默认返回NO表示默认不能同时识别两个手势
- gestureRecognizer: shouldRequireFailureOfGestureRecognizer:每次尝试识别手势都会调用,一般只会在手势冲突时候,比如同时添加轻击手势和长按手势,轻击手势设置代理,在区分是轻击手势或者长按手势还没有确定结果的时候调用,而不设置轻击手势代理而设置长按代理的时候就不会调用
- gestureRecognizer: shouldBeRequiredToFailByGestureRecognizer:调用时机同上
- gestureRecognizer: shouldReceiveTouch:在上面两个方法之前调用
- gestureRecognizer: shouldReceivePress:同上

自定义手势

  1. 继承自UIGestureRecognizer, 在实现文件添加#import 头文件的引用
  2. 维护两种状态转变方式:
1
2
Possible--->Began--->[Changed]--->Cancelled
Possible--->Began--->[Changed]--->Ended

为此,根据需要,重载在UIGestureRecognizerSubclass.h所声明的方法,在方法中设置好self.state = UIGestureRecognizerStateCancelled;和 self.state = UIGestureRecognizerSateEnded 的值:

1
2
3
4
5
6
- touchesBegan:withEvent:
- touchesMoved:withEvent:
- touchesEnded:withEvent:
- touchesCancelled:withEvent:
- reset
...

参考

API之UIGestureRecognizer及自定义手势

文章目录
  1. 1. UIResponder传递路径
  2. 2. UIResponder触碰响应方法
  3. 3. 系统手势处理器(UIGestureRecognizer)
  4. 4. 手势冲突
  5. 5. 自定义手势
  6. 6. 参考