IOS 手势事件的冲突

关于手操作需要强调几点:

  • UIImageView默认是不支持交互的,也就是userInteractionEnabled=NO ,因此要接收触摸事件(手势识别),必须设置userInteractionEnabled=YES(在iOS中UILabel、UIImageView的userInteractionEnabled默认都是NO,UIButton、UITextField、UIScrollView、UITableView等默认都是YES)。
  • 轻扫手势虽然是连续手势但是它的操作事件只会在识别结束时调用一次,其他连续手势都会调用多次,一般需要进行状态判断;此外轻扫手势支持四个方向,但是如果要支持多个方向需要添加多个轻扫手势。

手势冲突

细心的童鞋会发现在上面的演示效果图中当切换到下一张或者上一张图片时并没有轻扫图片而是在空白地方轻扫完成,原因是如果我轻扫图片会引起拖动手势而不是轻扫手势。换句话说,两种手势发生了冲突。

冲突的原因很简单,拖动手势的操作事件是在手势的开始状态(状态1)识别执行的,而轻扫手势的操作事件只有在手势结束状态(状态3)才能执行,因此轻扫手势就作为了牺牲品没有被正确识别。我们理想的情况当然是如果在图片上拖动就移动图片,如果在图片上轻扫就翻动图片。如何解决这个冲突呢?

在iOS中,如果一个手势A的识别部分是另一个手势B的子部分时,默认情况下A就会先识别,B就无法识别了。要解决这个冲突可以利用- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;方法来完成。正是前面表格中UIGestureRecognizer的最后一个方法,这个方法可以指定某个手势执行的前提是另一个手势失败才会识别执行。也就是说如果我们指定拖动手势的执行前提为轻扫手势失败就可以了,这样一来当我们手指轻轻滑动时系统会优先考虑轻扫手势,如果最后发现该操作不是轻扫,那么就会执行拖动。只要将下面的代码添加到添加手势之后就能解决这个问题了(注意为了更加清晰的区分拖动和轻扫[模拟器中拖动稍微快一点就识别成了轻扫],这里将长按手势的前提设置为拖动失败,避免演示拖动时长按手势会被识别):

    //解决在图片上滑动时拖动手势和轻扫手势的冲突
    [panGesture requireGestureRecognizerToFail:swipeGestureToRight];
    [panGesture requireGestureRecognizerToFail:swipeGestureToLeft];
    //解决拖动和长按手势之间的冲突
    [longPressGesture requireGestureRecognizerToFail:panGesture];

两个不同控件的手势同时执行

我们知道在iOS的触摸事件中,事件触发是根据响应者链进行的,上层触摸事件执行后就不再向下传播。默认情况下手势也是类似的,先识别的手势会阻断手势识别操作继续传播。那么如何让两个有层次关系并且都添加了手势的控件都能正确识别手势呢?答案就是利用代理的-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer方法。这个代理方法默认返回NO,会阻断继续向下识别手势,如果返回YES则可以继续向下传播识别。

摘自:http://www.cnblogs.com/kenshincui/p/3950646.html  崔江涛  感谢博主

 
时间: 2024-10-04 12:33:06

IOS 手势事件的冲突的相关文章

ios多手势事件

开发ios应用时我们经常用到多手势来处理事情,如给scrollView增加点击事件,scrollView不能响应view的touch事件,但有时候却要用到多手势事件,那么我们可以给这个scrollView增加自己的手指事件.给imageView增加点击.放大.旋转等都可以通过多手势来完成. 下面就介绍下各种的手势的使用方法,及注意事项. - (void)viewDidLoad { [super viewDidLoad]; //为了能响应多手势事件,imageView的userInteractio

iOS 手势滑动事件绑定

UIGestureRecognizer 手势响应基类- UITapGestureRecognizer //点击手势识别器,可以是点击一次,或多次都能识别- UIPinchGestureRecognizer //捏合手势识别器,用于视图的放大缩小- UIRotationGestureRecognizer //旋转手势识别器- UISwipeGestureRecognizer //滑动手势识别器,向上.下.左.右滑动- UIPanGestureRecognizer //拖动手势识别器- UILong

IOS开发中长按的手势事件编程

长按手势事件: 长按按钮1S后改变按钮颜色: 1 // 长按事件 2 #import "ViewController.h" 3 @interface ViewController (){ 4 UIButton *myBtn; 5 } 6 @end 7 @implementation ViewController 8 - (void)viewDidLoad { 9 [super viewDidLoad]; 10 myBtn = [[UIButton alloc]initWithFrame

iOS手势 规避同一界面上不同子界面同时响应多个手势

最近在项目中遇到这样一个有关iOS手势的问题,首先需求描述如下:“在一个CollectionView中,要求长按不同的cell,产生一个cell的snapshot,此时可拖拽这个snapshot再进行后续的操作(如拖到view的某个位置出发一个事件)”.需求本身并不复杂,但要求每次只能有一个cell响应长按手势,不允许同时有两个或以上的cell响应长按手势. 我们知道UIGestureRecognizer有很多回调和方法可以兼容同一个View上的多种手势,网上相关的教程也很多,比如: http:

iOS 手势识别器概述

手势识别器 iOS 手势识别器(UIGestureRecognizer) 点击手势(UITapGestureRecognizer) 滑动手势(UISwipeGestureRecognizer) 旋转手势(UIRotationGestureRecognizer) 捏合手势( UIPinchGestureRecognizer) 长按手势( UILongPressGestureRecognizer) 平移手势( UIPanGestureRecognizer) 屏幕边缘平移手势(UIScreenEdge

iOS开发 - 事件传递响应链

一.序言 当我们在使用微信等工具,点击扫一扫,就能打开二维码扫描视图.在我们点击屏幕的时候,iphone OS获取到了用户进行了"单击"这一行为,操作系统把包含这些点击事件的信息包装成UITouch和UIEvent形式的实例,然后找到当前运行的程序,逐级寻找能够响应这个事件的对象,直到没有响应者响应.这一寻找的过程,被称作事件的响应链,如下图所示,不用的响应者以链式的方式寻找. 事件响应链: 二.响应者 在iOS中,能够响应事件的对象都是UIResponder的子类对象.UIRespo

iOS手势处理

iOS手势处理 iOS手势有着如下几种: UITapGestureRecognizer UIPinchGestureRecognizer UIRotationGestureRecognizer UISwipeGestureRecognizer UIPanGestureRecognizer UILongPressGestureRecognizer 上面的手势对应的操作是: Tap          (点一下) Pinch        (二指往內或往外拨动,平时经常用到的缩放)  矩阵变换 Rot

IOS触摸事件和手势识别

IOS触摸事件和手势识别 目录 概述 触摸事件 手势识别 概述 为了实现一些新的需求,我们常常需要给IOS添加触摸事件和手势识别 触摸事件 触摸事件的四种方法 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 开始触摸所触发的方法 -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 移动时触发的方法 -(void)touchesEnded:(N

iOS手势识别器

UIGestureRecognizer UIGestureRecognizer类,用于检测.识别用户使用设备时所用的手势.它是一个抽象类,定义了所有手势的基本行为.以下是UIGestureRecognizer子类,用于处理具体的用户手势行为: UITapGestureRecognizer // 1.单击 UILongPressGestureRecognizer // 3.长按 UISwipeGestureRecognizer // 4.轻扫 UIPanGestureRecognizer // 5