iOS开发之手势识别
一、uigesturerecognizer简单介绍
我们已经学习了触摸事件处理,但触摸事件处理起来很麻烦,每个触摸事件处理都需要实现3个touches方法,比较繁琐,实际上我们可以使用更加简单的触摸事件处理操作,那就是 手势识别uigesturerecognizer 。
手势识别操作基类uigesturerecognizer不能直接使用,我们常使用的是它的子类,这些手势操作类都继承自uigesturerecognizer类
常用手势识别子类:
点按手势 uitapgesturerecognizer
捏合手势 uipinchgesturerecognizer
拖动手势 uipangesturerecognizer
轻扫手势 uiswipegesturerecognizer【4个方向分离】
旋转手势 uirotationgesturerecognizer
长按手势 uilongpressgesturerecognizer
二、uigesturerecognizer属性
对象属性:
@property (nonatomic , readonly) uigesturerecognizerstate state;/*< 手势状态 */
@property (nonatomic , getter=isenabled) bool enabled;/*< 手势是否可用 */
@property (nonatomic , readonly) uiview *view;/*< 触发手势的视图 */
@property (nonatomic , assign) bool delaystouchesbegan;/*< 手势识别失败前不执行触摸开始事件,默认为no */
手势识别状态state:
typedef ns_enum(nsinteger, uigesturerecognizerstate) {
uigesturerecognizerstatepossible, // 尚未识别是何种手势操作(但可能已经触发了触摸事件),默认状态
uigesturerecognizerstatebegan, // 手势已经开始,此时已经被识别,但是这个过程中可能发生变化,手势操作尚未完成
uigesturerecognizerstatechanged, // 手势状态发生转变
uigesturerecognizerstateended, // 手势识别操作完成(此时已经松开手指)
uigesturerecognizerstatecancelled, // 手势被取消,恢复到默认状态
uigesturerecognizerstatefailed, // 手势识别失败,恢复到默认状态
uigesturerecognizerstaterecognized = uigesturerecognizerstateended // 手势识别完成,同uigesturerecognizerstateended
};
左图为 短手势 的状态转变,右图为 长手势 的状态转变
三、uigesturerecognizer方法
#pragmx mark 添加触摸执行事件
- (void)addtarget:(id)target action:(sel)action;
#pragma mark 移除触摸执行事件
- (void)removetarget:(id)target action:(sel)action;
#pragma mark 触摸点的个数(同时触摸的手指数)
- (nsuinteger)numberoftouches;
#pragma mark 在指定视图中的相对位置
- (cgpoint)locationinview:(uiview*)view;
#pragma mark 触摸点相对于指定视图的位置
- (cgpoint)locationoftouch:(nsuinteger)touchindex inview:(uiview*)view;
#pragma mark 指定一个手势需要另一个手势执行失败才会执行
- (void)requiregesturerecognizertofail:(uigesturerecognizer *)othergesturerecognizer;
四、uigesturerecognizer使用
# 创建手势识别器对象
uitapgesturerecognizer *tap = [[uitapgesturerecognizer alloc] init];
# 设置手势识别器对象的具体属性
tap.numberoftapsrequired = 2; // 连续敲击2次
tap.numberoftouchesrequired = 2;// 需要2根手指一起敲击
# 添加手势识别器到对应的view上
[self.myview addgesturerecognizer:tap];
# 监听手势的触发
[tap addtarget:self action:@selector(tapview:)];
五、多手势冲突
在ios中,如果一个手势a的识别部分是另一个手势b的子部分,默认情况下a就会先识别,b就无法识别了,
比如拖动手势a和轻扫手势b,轻扫手势只在手势结束状态才能执行,而拖动手势在手势开始的时候执行,这两个手势一起触发,轻扫手势就成了牺牲品。
解决手势冲突,就是利用一个方法:
-(void)requiregesturerecognizertofail:(uigesturerecognizer *)othergesturerecognizer
该方法指定一个手势需要另外一个手势识别失败才会执行
比如解决拖动手势和轻扫手势冲突:
// 拖动手势的执行需要右轻扫手势的失败为前提
[pangesture requiregesturerecognizertofail:swipegesturetoright];
// 拖动手势的执行需要左轻扫手势的失败为前提
[pangesture requiregesturerecognizertofail:swipegesturetoleft];
六、uigesturerecognizerdelegate代理
代理方法:
#pragma mark 一个控件识别手势后是否沿着响应者链条继续传播手势识别,默认返回no
- (bool)gesturerecognizer:(uigesturerecognizer *)gesturerecognizer shouldrecognizesimultaneouslywithgesturerecognizer:(uigesturerecognizer *)othergesturerecognizer;
用该代理方法可以实现两个不同控件的手势同时执行,需要让该方法返回yes,手势识别就能传递给不同控件