UIGestureRecognizer

2016-05-20 | 阅读

UIGestureRecognizer

UIGestureRecognizer 常用的方法和属性有:

// 初始化,而一般处理的函数形式为-(void)handleGesture:(UIGestureRecognizer*)gestureRecognizer; ,对于持续性的滑动之类的手势,是会一直调用这个函数来传递手势信息的.
- (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action
// 当前手势状态.
@property(nonatomic,readonly) UIGestureRecognizerState state;
状态有以下几种:
UIGestureRecognizerStatePossible, // 手势当前不确定,可能是其他手势,也可能是无用的点击,这个是最开始的默认状态.
UIGestureRecognizerStateBegan,  // 已经确定是手势,且接收到touch,触发这个之后,就会在下一个时钟周期时向target发送消息
UIGestureRecognizerStateChanged,  // 手势状态改变,发生了移动,调用targetAction
UIGestureRecognizerStateEnded, // 手势结束,状态改为Possible,依旧调用target.
UIGestureRecognizerStateCancelled,   // 取消,状态改为Possible ,调用target
UIGestureRecognizerStateFailed,   // 手势失败,这次手势序列结束,targetAction不会被调用,状态改为Possible
UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded 

// 手势的代理
@property(nullable,nonatomic,weak) id <UIGestureRecognizerDelegate> delegate; 
// 是否可用,如果为NO,这个recognizer将不再接受点击事件 . 如果当前有手势正在处理,而设置为NO,则会将状态修改为UIGestureRecognizerStateCancelled.

@property(nonatomic, getter=isEnabled) BOOL enabled;
// 监听的view,接受这个view和所有子view的touch事件.

@property(nullable, nonatomic,readonly) UIView *view;   
 
// touch来了先让Recognizer来分析,如果能处理,就会取消这个View上其他的手势或者touch或者press事件,即拦截的效果,一个手势能处理时,就完全截断了这个事件,不再发给其他人,默认是YES.即如果当前除了手势还有touchBeign或者precessBegin这样的监听,就会调用touchesCancelled:withEvent: or pressesCancelled:withEvent:来取消.
@property(nonatomic) BOOL cancelsTouchesInView; 
// 延迟touchBegin或pressBegin的调用,只有当这个手势已经失败时,才会发送touchBegin:事件,默认是NO.即保证所有的点击事件都由recognize来处理.
@property(nonatomic) BOOL delaysTouchesBegan; 
// 延迟touchEnd或pressesEnded的调用,只有当recognizer识别失败后,才会调用相应的结束回调.
@property(nonatomic) BOOL delaysTouchesEnded; 

//允许的点击类型
@property(nonatomic, copy) NSArray<NSNumber *> *allowedTouchTypes;
// 允许的按压类型
@property(nonatomic, copy) NSArray<NSNumber *> *allowedPressTypes;

// 创建两个recognizer之间的关系, 当前这个recognizer必须等待otherGestureRecognizer的失败后,才能去进行响应.要注意的是,如果当前这个手势已经在响应了,但是otherGestureRecognizer的状态突然变为UIGestureRecognizerStateRecognized或UIGestureRecognizerStateBegan ,即也开始响应的时候,则本recognizer就会变成失败UIGestureRecognizerStateFailed. 举例,就是 单击事件需要一个双击事件先去失败.
- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;

// 当前点击的数量
- (NSUInteger)numberOfTouches;  
// 如果只有一个点击,调用这个方法,获得点击在View上的位置.
- (CGPoint)locationInView:(nullable UIView*)view;
//如果有多个点击,则需要根据序号查找每个点击的位置
- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view;  

UIGestureRecognizerDelegate

然后在详细研究一下 UIGestureRecognizerDelegate:

// 手势识别将要开始,这个方法会在UIGestureRecognizerStatePossible状态下调用,以确认是否处理手势.返回NO,将转换手势为UIGestureRecognizerStateFailed失败,一次touch事件,只会在最开始的时候调用这个函数一次.
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;

//两个手势是否能同时处理,默认是返回NO.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;

//每一次移动时都会调用该函数,返回YES时,即一个手势依赖另外一个手势的失败,这个方法与requireGestureRecognizerToFail的区别在于,前者是静态的,在初始化就要设置依赖的手势,而后者,即这里是动态的,在执行时才知道哪些recognizer是需要被失败依赖的.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

// 在recognizer处理之前,先判断这个touch是否是需要的.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press;

Touch事件是一个连续的过程,如果在第一次触碰被忽略,则在touch事件完成前,不会再来询问Recognizer.所以一般手势的处理是,先根据位置判断是否可以触发手势,然后在手势的具体处理中来判断,手势是否满足自己需要的动作样式,如滑动,是否滑动了一定距离,然后再设置手势完成,给予响应.

手势识别,封装了一些简单的手势操作,如:

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