所有的手势操作都继承于UIGestureRecognizer,这个类本身不能直接使用
IOS有六种手势操作
手势 | 说明 |
---|---|
UITapGestureRecognizer | 点按手势 |
UIPinchGestureRecognizer | 捏合手势 |
UIPanGestureRecognizer | 拖动手势 |
UISwipeGestureRecognizer | 轻扫手势,支持四个方向的轻扫,但是不同的方向要分别定义轻扫手势 |
UIRotationGestureRecognizer | 旋转手势 |
UILongPressGestureRecognizer | 长按手势 |
备注:
1、UIImageView默认是不支持交互的,也就是userInteractionEnabled=NO ,因此要接收触摸事件(手势识别),必须设置
userInteractionEnabled=YES(在iOS中UILabel、UIImageView的userInteractionEnabled默认都是NO,UIButton、UITextField、
UIScrollView、UITableView等默认都是YES)
2、轻扫手势虽然是连续手势但是它的操作事件只会在识别结束时调用一次,其他连续手势都会调用多次,一般需要进行状态判断;此外轻
扫手势支持四个方向,但是如果要支持多个方向需要添加多个轻扫手势
3、手势冲突
冲突的原因很简单,拖动手势的操作事件是在手势的开始状态(状态1)识别执行的,而轻扫手势的操作事件只有在手势结束状态(状
态3)才能执行,因此轻扫手势就作为了牺牲品没有被正确识别。我们理想的情况当然是如果在图片上拖动就移动图片,如果在图片上
轻扫就翻动图片。如何解决这个冲突呢?
在iOS中,如果一个手势A的识别部分是另一个手势B的子部分时,默认情况下A就会先识别,B就无法识别了。要解决这个冲突可以利
用- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;方法来完成。这个方法可
以指定某个手势执行的前提是另一个手势失败才会识别执行。也就是说如果我们指定拖动手势的执行前提为轻扫手势失败就可以了,这
样一来当我们手指轻轻滑动时系统会优先考虑轻扫手势,如果最后发现该操作不是轻扫,那么就会执行拖动。只要将下面的代码添加到
添加手势之后就能解决这个问题了。例如:[panGesture requireGestureRecognizerToFail:swipeGestureToRight];
UIGestureRecognizer这个类中定义了这几种手势共有的一些属性和方法(下表仅列出常用属性和方法):
名称 | 说明 |
---|---|
属性 |
|
@property(nonatomic,readonly) UIGestureRecognizerState state; | 手势状态 |
@property(nonatomic, getter=isEnabled) BOOL enabled; | 手势是否可用 |
@property(nonatomic,readonly) UIView *view; | 触发手势的视图(一般在触摸执行操作中我们可以通过此属性获得触摸视图进行操作) |
@property(nonatomic) BOOL delaysTouchesBegan; | 手势识别失败前不执行触摸开始事件,默认为NO;如果为YES,那么成功识别则不执行触摸开始事件,失败则执行触摸开始事件;如果为NO,则不管成功与否都执行触摸开始事件; |
方法 |
|
- (void)addTarget:(id)target action:(SEL)action; | 添加触摸执行事件 |
- (void)removeTarget:(id)target action:(SEL)action; | 移除触摸执行事件 |
- (NSUInteger)numberOfTouches; | 触摸点的个数(同时触摸的手指数) |
- (CGPoint)locationInView:(UIView*)view; | 在指定视图中的相对位置 |
- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(UIView*)view; | 触摸点相对于指定视图的位置 |
- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer; | 指定一个手势需要另一个手势执行失败才会执行 |
代理方法 |
|
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer; | 一个控件的手势识别后是否阻断手势识别继续向下传播,默认返回NO;如果为YES,响应者链上层对象触发手势识别后,如果下层对象也添加了手势并成功识别也会继续执行,否则上层对象识别后则不再继续传播; |