之前做优质派时写了个仿网易新闻导航的第三方,由于当时做项目时这个主控制器就是RootViewController,虽然用的是ScrollView但也没考虑到导航栏的手势返回的问题 ,现在做小区宝3.0的闪购订单,用之前的就有问题了。导航栏的返回手势用不了,根据响应者链和响应事件,手势被ScrollView识别了,就到不了导航的手势识别,所以导致无法手势返回。

要解决这个问题首先要了解下手势识别代理:

iOS的手势识别模型其实是一个状态机

所有手势识别从一个可能状态(UIGestureRecognizerStatePossible)开始,然后开始分析、识别手势,如果识别失败将会进入失败状(UIGestureRecognizerStateFailed)。
如果识别成功,进入成功状态(UIGestureRecognizerStateRecognized)
对于连续性的手势,手势识别从Possible进入Began(UIGestureRecognizerStateBegan) ,然后会进入Change (UIGestureRecognizerStateChanged)状态,并在Change状态循环,在最后用户手指离开屏幕的时候会进入End(UIGestureRecognizerStateEnded)状态
连续手势也会从Change进入cancel (UIGestureRecognizerStateCancelled),如果判断手势已经不符合该要求了。
每次Gesture recognizer改变状态的时候都会发送一个action message到target,知道Failed或者Cancel。
有时候会出现iOS判断该手势符合多个条件,而用户此时只想要其中一种,这个情况下可以调用 requireGestureRecognizerToFail: ,该方法会让当前手势对象根据指定对象状态来进行下一步操作。如果指定对象进入Begin状态,当前对象直接进入Failed;如果指定对象进入Failed或Cancel状态,当前对象会进入Begin状态。这里就涉及到了不同手势之间执行的问题。(如果想要单击和双击都要执行,并分别执行不同的逻辑,这里可以先让单机等待双击失败在执行,但这样会导致单击事件稍微延迟执行,因为单击事件需要等待双击事件失败)。
可以选择不让接收、分析手势事件,通过 gestureRecognizer:shouldReceiveTouch: 在最开始的时候允许、拒绝接收手势时间;如果想延后判断则可以通过 gestureRecognizerShouldBegin:,如果返回No则会导致Failed时间
如果想要同时接收两个事件,就调用gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: 默认这个方法返回No,返回Yes则运行同时运行
单向影响,事件A和B, 如果想要让A影响B,但不想让B影响A,则可以通过重载方法 canPreventGestureRecognizer: 或者canBePreventedByGestureRecognizer:实现,比如
[rotationGestureRecognizer canPreventGestureRecognizer:pinchGestureRecognizer];
Touch事件传递过程是上到下,也就是从App->Window->View的过程
Touch事件,window会让Gesture recognizer优先分析touch对象,如果Gesture recognizer成功识别这些对象,touch事件就不会执行。总结就是Gesture recognizer的优先级会低于touch事件
影响touch传递给views
delaysTouchesBegan 阻止在Begin阶段Windows交付touch事件
delaysTouchesEnded Window不会在Enable阶段交付Touch事件
Gesture Recognizer是iOS定制的一些Touch事件类型,Dev可以订制自己的Gesture Recognizer,这里要继承UIGestureRecognizer并覆盖主要的四个类。

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;

返回值是返回是否生效。此方法在gesture recognizer视图转出UIGestureRecognizerStatePossible状态时调用,如果返回NO,则转换到UIGestureRecognizerStateFailed;如果返回YES,则继续识别触摸序列.(默认情况下为YES)

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;

这个方法返回值是用来表示手势是否共存的。只要返回YES,另外就不用管了,因为共存,所以共存,共同响应.也就是说两个gesture recognizers的delegate方法只要任意一个返回YES,则这两个就可以同时识别;只有两个都返回NO的时候,才是互斥的。默认情况下是返回NO。

一个控件的手势识别后是否阻断手势识别继续向下传播,默认返回NO;如果为YES,响应者链上层对象触发手势识别后,如果下层对象也添加了手势并成功识别也会继续执行,否则上层对象识别后则不再继续传播;

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);

这个两个成对的方法比较有趣,一个是前面失效后面生效,另外一个相反

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;

在toucheBegan这个方法之前,也就是在手势状态为began之前?

此方法在window对象在有触摸事件发生时,调用gesture recognizer的touchesBegan:withEvent:方法之前调用,如果返回NO,则gesture recognizer不会看到此触摸事件。(默认情况下为YES).

ios手势识别代理的更多相关文章

  1. iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势)

    iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势)       1.UIGestureRecognizer介绍 手势识别在iOS上非常重要,手势操作移动设备的重要特征,极大的增加 ...

  2. ios iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势)

    iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势) 转自容芳志大神的博客:http://www.cnblogs.com/stoic/archive/2013/02/27/2940 ...

  3. iOS手势识别

    一.手势识别与触摸事件 1.如果想监听一个view上面的触摸事件,可选的做法是: (1)自定义一个view (2)实现view的touches方法,在方法内部实现具体处理代码 2.通过touches方 ...

  4. iOS 设置代理过程

    iOS设置代理的过程 (以模拟 button 作用为例) 1.写协议 新建一个名为 MyButton 的文件,继承于 UIView,在该文件里 声明协议 myDelegate 2.写协议方法 为声明的 ...

  5. iOS设计模式 - 代理

    iOS设计模式 - 代理 原理图 说明 1. 代理模式大家都用过,但用抽象基类NSProxy实现代理估计鲜有人用 2. 本人用NSProxy实现了代理模式,对于理解消息转发机制有点帮助 源码 http ...

  6. UIGestureRecognizer ios手势识别温习

    1.UIGestureRecognizer介绍 手势识别在iOS上非常重要,手势操作移动设备的重要特征,极大的增加了移动设备使用便捷性. iOS系统在3.2以后,为方便开发这使用一些常用的手势,提供了 ...

  7. 【转】iOS手势识别的详细使用(拖动,缩放,旋转,点击,手势依赖,自定义手势) -- 不错不错

    原文网址:http://blog.csdn.net/totogo2010/article/details/8615940 1.UIGestureRecognizer介绍 手势识别在iOS上非常重要,手 ...

  8. iOS,手势识别简单使用

    1.iOS目前支持的手势识别(6种) 2.点按手势和慢速拖动手势简单使用 iOS目前支持的手势识别(6种) UITapGestureRecognizer(点按) UIPinchGestureRecog ...

  9. ios透明代理抓包

    之前接到一些ios测试的时候,一些应用往往由于这样那样的原因(比如自实现的发包函数)导致直接使用本地ios系统的代理很难将数据代理到主机的burp或findler中,本文提供了一种解决该问题的途径 原 ...

随机推荐

  1. JavaScript日期(参考资料)

    构造函数1.new Date() 如果没有参数,则Date的构造器会依据系统设置的当前时间来创建一个Date对象.2.new Date(value) value代表自1970年1月1日00:00:00 ...

  2. SQL Server中将多行数据拼接为一行数据并且有特殊字符

    有表结构如下: 这时,要求显示所有学生的爱好的结果集,代码如下: ) as hobby FROM ( SELECT name, (SELECT hobby+',' FROM student WHERE ...

  3. TestNG参数化之@Parameters传参

    通过TestNG实现参数话常用两种方式,一种是借助 @Parameters读取testng.xml中参数,一种是使用@DataProvider注解传参. 此次主要讲解XML传参,语法:在java类中定 ...

  4. python中的列表和元组

    1. 什么是列表 定义: 能装对象的对象 在python中使用[]来描述列表, 内部元素用逗号隔开. 对数据类型没有要求,列表存在索引和切片. 和字符串是一样的. 2.相关的增删改查操作 切片 列表和 ...

  5. 八.linux系统文件属性知识

    1.文件属性权限是12位,现在只看9位,其中每3个一组,为:属主权限.属组权限.其他权限,其中r可读,w可写,x可执行,如图: 2.文件属性之软硬链接   linux系统中有两种链接,为硬链接(ln) ...

  6. C - Oil Deposits(dfs)

    点击打开链接 Oil Deposits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe ...

  7. Python(re模块,正则)

    day18 正则表达式用处? 匹配 字符串 s = 'hello world' print(s.find('llo'))#第一个的位置 ret = s.replace('ll','xx') print ...

  8. php 递归数据,三维数组转换二维

    public function sortarea($area, $parent_id = 0, $lev = 1){ static $list; foreach($area as $v){ if($v ...

  9. SpringMVC中重定向传参数的方法

    在spring的一个controller中要把参数传到页面,只要配置视图解析器,把参数添加到Model中,在页面用el表达式就可以取到.但是,这样使用的是forward方式,浏览器的地址栏是不变的,如 ...

  10. 使HTML页面上获取到的文本保留空格和换行符等格式

    <pre> 元素可定义预格式化的文本.被包围在 pre 元素中的文本通常会保留空格和换行符.而文本也会呈现为等宽字体.   <pre>的内容自动换行的问题(兼容多个浏览器): ...