触摸传递 Touch Delivery
下面是一个触摸传递到视图和手势识别的完整的标准过程:
当有一个新的触摸,该应用程序使用hit-testing命中测试(后面会讲)来确定被触摸的视图,这个视图就会永远与这个触摸对应。这个视图称为hit-test视图。如果想忽略一个视图,不处理触摸,可以在这个阶段设置userInteractionEnabled, hidden, 和 alpha属性。
每次触摸状态改变,该应用程序会调用自己的sendEvent:方法,反过来又会调用window的sendEvent:方法,这个window会通过调用那几个touches...方法来传递每个事件的触摸,如下所述:
当一个触摸第一次出现时,会考虑这个视图是否服从这个multipleTouchEnabled 和 exclusiveTouch逻辑,如果这个逻辑被允许,就会:
a. 这个触摸会传递给这个hit-test视图的所有手势识别。
b. 这个触摸会传递给hit-test视图本身。
如果这个手势被一个手势识别所识别,那么对于任何与这个手势识别相关的触摸就会:
a. touchesCancelled:forEvent:消息会发送给触摸的视图,这个触摸不再传递给它对应的视图。
b. 如果这个触摸与任何其它的手势识别相关,这个手势识别会强制进入失败状态。
如果一个手势识别失败,可能是因为它宣告失败,或因为它是被迫失败,它相关的触摸倒是不再传递给它,但(已经规定的情况除外),触摸会继续被传递到它们的视图。
如果一个触摸将要传递到一个视图,如果这个视图没有响应相应的touches...方法,响应者会从响应者链向上查找可以响应的响应者,然后传递触摸给它。
hit-testing
hit-testing 是用来决定哪个视图被用户触摸了。通过使用视图的实例方法 hitTest:withEvent:,返回一个视图(hit-testing 视图)或者nil,目的是返回包含触摸点的最前面的视图。这个方法使用了一个优雅的递归算法,如下:
一个视图的hitTest:withEvent:里面会首先调用它子视图的同样方法,查找是否有hit-testing视图,因为子视图总是在父视图的前面。然后这个子视图在hitTest:withEvent:方法里面还是以相反的顺序调用它子视图的同样方法。如果两个同级的子视图重叠了,会返回最前面的那个视图。
如果一个视图hit-testing它的子视图,任何一个子视图一旦返回一个视图,那么它就会停止查询它的子视图,立刻同样返回这个视图。第一个返回的hit-test视图会沿调用链返回到顶端,这个就是最终的hit-test视图。
如果,另一方面,一个视图没有子视图,或者它的所有子视图都返回nil(表明这视图和它的子视图都没有被点击),那么这个视图就会调用它自己的pointInside:withEvent:方法。如果这个调用结果显示这个触摸是在这个视图里面的,视图会返回自身,表明它本身是hit-test 视图,否则,它返回nil。
如果一个视图有一个转换,这个仍然是正常工作的,因为pointInside:withEvent:会把视图的转换考虑进去。这就是为什么一个旋转了的button仍然正常工作。
Recognition
当一个手势识别器识别了它的手势,所有的东西都会变化。这个手势识别对应的touches 会被发送到它们的hit-test 视图的touchesCancelled:forEvent: 消息里,然后就不再到达这些视图了(除非这个手势识别的cancelsTouchesInView属性为NO)。另外,所有其它的手势识别对于这些触摸都会变成失败,同时也不再发送这些touches给这些手势识别。
依赖顺序
下面的方法建立了一个相关性顺序,使某个手势识别在其他的手势识别失败时才允许从Possible状态进入Began状态或者进入Ended状态:
UIGestureRecognizer 的 requireGestureRecognizerToFail:(发送到一个手势识别)
UIGestureRecognizer 的 shouldRequireFailureOfGestureRecognizer:(在子类中重写)
UIGestureRecognizer 的 shouldBeRequiredToFailByGestureRecognizer: (在子类中重写)
委托的 gestureRecognizer:shouldRequireFailureOfGestureRecognizer:
委托的 gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer:
上面的第一个方法设置了两个手势识别的永久关系,不能撤销。其它方法就会在一个手势在视图中产生时调用,结果只适用于这个时间上的手势。
这些委托方法执行的顺序如下:对于在hit-test视图中的每对手势识别,这一对中的第一个会被发送shouldRequire消息,然后是shouldBeRequired消息,接着这一对中的第二个会被发送shouldRequire消息,然后是shouldBeRequired消息。如果任何这四种方法返回了YES,这对手势识别的关系就确定了,当前的调用序列结束,开始下一对手势识别。
成功状态到失败状态
当一个手势识别器将要声明它识别了一个手势时,如果下面的方法返回NO,会把这个手势识别强制从成功状态转到失败状态:
UIView 的 gestureRecognizerShouldBegin: (hit-test视图子类重写)
委托的gestureRecognizerShouldBegin:
同时识别手势
一个手势识别成功了,但是其它的手势识别没有强制变成失败状态,由下面的方法决定:
委托的gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:
UIGestureRecognizer 的 canPreventGestureRecognizer:(在子类中重写)
UIGestureRecognizer 的 canBePreventedByGestureRecognizer: (在子类中重写)
在子类中重写的方法名称中的“prevent” 表示“这个手势识别成功是建立在强制其它的手势失败的基础上”, 名称中的“be prevented” 表示“其它手势识别失败是建立在你这个手势识别成功”。调用顺序是:
首先调用canPreventGestureRecognizer:方法,如果返回NO,这个手势识别结束。
然后在另一个手势识别器上调用 canPreventGestureRecognizer:,如果第一次调用这个方法时返回YES,这个手势识别器会发送canBePreventedByGestureRecognizer:消息,如果这个方法也返回YES,那么这个手势识别器结束,如果返回NO,会给第二个手势识别发送 canPreventGestureRecognizer:消息,重新从1开始。
这样就解决了手势识别冲突的问题。
转载于:https://www.cnblogs.com/YungMing/p/4050134.html
触摸传递 Touch Delivery相关推荐
- Unity 进阶 之 简单模仿鼠标交互(场景:手机屏幕当做触摸板Touch Pad,移动鼠标,鼠标确定等操作)
Unity 进阶 之 简单模仿鼠标交互(场景:手机屏幕当做触摸板Touch Pad,移动鼠标,鼠标确定等操作) 目录 Unity 进阶 之 简单模仿鼠标交互(场景:手机屏幕当做触摸板Touch Pad ...
- JS事件监听手机屏幕触摸事件 Touch
JS移动客户端--触屏滑动事件 移动端触屏滑动的效果其实就是图片轮播,在PC的页面上很好实现,绑定click和mouseover等事件来完成.但是在移动设备上,要实现这种轮播的效果,就需要用到核心的t ...
- U3D如何调用Win10的触摸键盘Touch KeyBoard非屏幕键盘(OSK.exe)
最近一个项目要用到Windows的触摸键盘的功能,试过OSK屏幕键盘总感觉不怎么好用,试了下Win10自带的TabTip触摸键盘发现比较符合要求这里贴上U3D呼出和隐藏触摸键盘Touch KeyBoa ...
- js触摸(touch)事件
移动端触摸(touch)事件 移动端时代已经到来,作为前端开发的我们没有理由也不应该坐井观天,而是勇敢地跳出心里的那口井,去拥抱蔚蓝的天空.该来的总会来,我们要做的就是接受未知的挑战.正如你所看到的, ...
- Android 触摸事件(Touch)的传递机制
Touch 事件的传递机制 一个完整的touch 事件,由一个 down 事件.n 个 move 事件,一个 up 事件组成. Touch 事 件 一 般 的 传 递 流 程 Activity--&g ...
- iOS UITouch触摸与UIGesture手势.01.事件、触摸(touch)事件
一.iOS事件: 1.事件:事件就是当你在手机上点击手机屏幕.滑动手机翻面.摇动手机的时候,手机做出一些反应,对应的在应用程序里实现了某些代码的某些功能,完成这个过程就是一个事件. 2.iOS事件类型 ...
- HTML5滑动(swipe)事件,移动端触摸(touch)事件
目有个交互需要实现手指滑动的交互,pc端使用mousedown,mousemove,mouseup监听实现. 但在ios设备上mousemove是不好监听的,同类的方法是touchstart,touc ...
- 触摸(touch)功能的原理和架构实现
1 目前车载touch的功能,采用的都是电容屏,分为incell和oncell的概念,主要是touch panel的位置不同,主要依据touch panel 和touch IC实现touch的触摸功能 ...
- 触摸(Touch)事件
Touch事件: touches:当前位于屏幕上的所有手指的一个列表 targetTouches:位于当前DOM元素上的手指的一个列表: changedTouches:涉及当前事件的手指的一个列表: ...
最新文章
- 用半机械器官,打开发育生物学领域的黑匣子
- python上机报告出现的问题和解决方法_关于发现存在问题及解决方法的报告
- OpenCV交互式相机校准应用
- hive的新分区和旧分区的概念问题
- vue监听对象某一个属性
- 58 集团大规模 Storm 任务平滑迁移至 Flink 的秘密
- docker 分布式管理群集_Coolpy7分布式物联网MQTT集群搭建
- 鸿蒙系统9月11号上市吗,9月11日鸿蒙系统2.0要搭载华为全家桶来了,你期待吗?...
- 获取结构体某成员偏移
- CMS内容管理系统可行性分析
- 关于PCB板热设计的学习总结
- matlab能打开mdl文件吗,simulink打开mdl文件的问题
- 基于Web的代码编辑器 Ace的使用
- 投稿状态(status)记录 IEEE wireless communications letters (IEEE WCL)
- ELK日志分析系统搭建以及springboot日志发送到ELK中
- 爬取公布的招聘信息(selenium实现)
- 【宋红康 MySQL数据库 】【高级篇】【03】MySQL的数据目录
- 初中数学与计算机论文,初中数学论文范文
- 江南大学2023年851真题回顾
- linux下 恢复gho镜像,手动使用ghost恢复win7系统gho镜像包教程
热门文章
- Dubbo学习笔记:No provider available for the service ...异常问题的解决
- 瞬息万变的技术圈与焦虑的技术人,进阶Android需要掌握的那几个关键技术!
- mysql定时任务,把7天的数据存到历史表,再删除7天前的数据
- Paypal学习 3 -- 接受信用卡直接付款 (DoDirectPayment)
- 复制链接到safari浏览器打开,如何从Safari浏览器获取网址
- 各种区块链浏览器的地址总汇
- [机器学习]1模型评估与选择
- 动态路由协议:华为路由配置OSPF实验
- 云原生kubernetes七 :Pod进阶篇:污点-容忍度-亲和性-Affinity-调度
- ubuntu分区大小