触摸发生时,UIWindow会有一个队列来存放所有的触摸事件,然后再把这些事件发送给对应的hit-test view,hit-test view会通过touch的四个函数来接收这些事件。

四个函数分别为:(began,move, end, cancel)

//touches method

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

NSLog(@"%s", __func__);

[super touchesBegan:touches withEvent:event];

}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

NSLog(@"%s", __func__);

[super touchesMoved:touches withEvent:event];

}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

NSLog(@"%s", __func__);

[super touchesEnded:touches withEvent:event];

}

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

NSLog(@"%s", __func__);

[super touchesCancelled:touches withEvent:event];

}

手势识别器同样有touch的四个函数,但是手势识别器本身并不继承自UIResponder,本身并不在响应链里,只有手势识别器对应的view在响应链中的时候手势识别器才会监听touch事件,并根据自己的touch函数识别手势,然后触发相应的回调函数。本质来说,hit-test view触摸事件的回调跟手势识别器是两个独立的过程,互不干涉,手势识别器先开始接收touch事件。但是手势识别中定义了三个属性,能够影响hit-test view触摸事件的调用过程,这三个属性如下所示:

gesture.cancelsTouchesInView

当值为YES时(默认值),表示手势识别成功后触摸事件取消掉,即识别成功后hitTest-View会调用touchesCancelled函数。

当值为NO时,触摸事件会正常起作用,会正常收到touchesEnded消息。

gesture.delaysTouchesBegan  = NO;

当值为NO时(默认值),触摸事件和手势识别的过程同时进行,当然先会发送触摸事件,然后当手势识别成功时,触摸事件会被取消掉,即识别成功后hitTest-View会调用touchesCancelled函数。

当值为YES时,手势识别器先接收touch事件进行手势识别,识别过程中hit-test view的触摸事件会先被UIWindow hold住,当手势识别成功时hit-test view的触摸事件不会调用,当手势识别失败时才开始调用touchesBegan函数。

gesture.delaysTouchesEnded = YES;

此属性差别比较小。

当值为YES时(默认值),当手势识别失败时会延迟(约0.15ms)调用touchesEnded函数。

当值为NO时,当手势识别失败时会立即调用touchesEnded函数。

delaysTouchesBegan、delaysTouchesEnded这两个属性决定是否在手势识别过程中向hit-test view发送触摸事件。

总结:触摸事件与手势识别是两个相对独立的过程,但是手势识别可以通过一些属性来影响触摸事件的调用,一般来说手势识别器的回调函数会比hit-test view的触摸事件的晚一些,因为手势识别器只有在手势识别出来之后才会触发回调函数(默认情况下只有一个手势识别器能够响应),但是手势识别器接收touch事件的时机比hit-test view早。

触摸事件过程:

触摸开始,找到first responder同时找到响应链,当响应链上没有手势识别器时,触摸事件通过first responder的响应链开始传递,如果响应链上有手势识别器,那么手势识别器先接收事件,然后再根据手势识别器的三个属性来决定是否同时将触摸事件传给first responder。

手势识别器原理:

手势识别器根据自身的四个touch函数来识别手势,例如长按、滑动等,手势识别器并不继承自UIResponder,因此它的四个touch函数不是UIResponder中的函数,而是UIResponder中这四个函数的镜像(说白了就是从UIResponder的头文件中复制粘贴过来的)。

由此可以推测UIButton的“按下”事件等也是根据四个Touch函数来实现的,因为UIButton继承自UIResponder,本身自带四个Touch函数。(经实验发现UIButton设置为enable时,在接收到触摸事件之后不会继续向上传递触摸事件,设置为disable时会向上传递触摸事件,但是加在UIButton上的tap手势不会起作用)

参考资料:

https://blog.csdn.net/petyou123/article/details/50893823

触摸事件,手势识别(UITouch,UIGestureRecognizer)的更多相关文章

  1. iOS基础 - 触摸事件&手势识别

    ================================================================== 一.触摸事件&手势识别 1> 4个触摸事件,针对视图 ...

  2. 阶段性总结⓵触摸事件&手势识别⓶Quartz2D绘图⓷CALayer图层⓸CAAnimation⓹UIDynamic UI动力学⓺KVC&KVO

    知识点复习   1. 触摸事件&手势识别   1> 4个触摸事件,针对视图的 2> 6个手势识别(除了用代码添加,也可以用Storyboard添加)   附加在某一个特定视图上的, ...

  3. iOS开发——UI进阶篇(十二)事件处理,触摸事件,UITouch,UIEvent,响应者链条,手势识别

    触摸事件 在用户使用app过程中,会产生各种各样的事件 一.iOS中的事件可以分为3大类型 触摸事件加速计事件远程控制事件 响应者对象在iOS中不是任何对象都能处理事件,只有继承了UIResponde ...

  4. iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控

    -- iOS事件全面解析 概览 iPhone的成功很大一部分得益于它多点触摸的强大功能,乔布斯让人们认识到手机其实是可以不用按键和手写笔直接操作的,这不愧为一项伟大的设计.今天我们就针对iOS的触摸事 ...

  5. IOS触摸事件和手势识别

    IOS触摸事件和手势识别 目录 概述 触摸事件 手势识别 概述 为了实现一些新的需求,我们常常需要给IOS添加触摸事件和手势识别 触摸事件 触摸事件的四种方法 -(void)touchesBegan: ...

  6. 转发:iOS开发系列--触摸事件、手势识别、摇晃事件、耳机线控

    -- iOS事件全面解析 转载来自崔江涛(KenshinCui) 链接:http://www.cnblogs.com/kenshincui/p/3950646.html 概览 iPhone的成功很大一 ...

  7. ios开发——实用技术OC-Swift篇&触摸与手势识别

    iOS开发学习之触摸事件和手势识别   iOS的输入事件 触摸事件 手势识别 手机摇晃 一.iOS的输入事件   触摸事件(滑动.点击) 运动事件(摇一摇.手机倾斜.行走),不需要人为参与的 远程控制 ...

  8. iOS_触摸事件与手势识别

    目  录: 一.触摸事件 1.1iOS的输入事件 1.2 触摸事件的处理 1.3 UITouch类中包含五个属性 1.4 UITouch类中包含两个成员函数 1.5响应者链 二.手势识别 2.1使用手 ...

  9. 【iOS系列】-触摸事件与手势识别

    [iOS系列]-触摸事件与手势识别 第一:触摸事件 一根手指触摸屏幕时,会创建一个与手指相关联的UITouch对象 UIEvent:称为事件对象,记录事件产生的时刻和类型 两根手指同时触摸一个view ...

随机推荐

  1. AWS Tagging Strategies

    How should I tag my AWS resources? Amazon Web Services (AWS) allows customers to assign metadata to ...

  2. 压力测试:系统吞吐量、TPS(QPS)、用户并发量、性能测试概念和公式

    PS:下面是性能测试的主要概念和计算公式,记录下: 一.系统吞度量要素: 一个系统的吞度量(承压能力)与request对CPU的消耗.外部接口.IO等等紧密关联.单个reqeust 对CPU消耗越高, ...

  3. 工控随笔_13_西门子_WinCC的VBS脚本_04_变量类型之二

    上一个随笔说了一些关于vbs变量类型的内容,这一篇我们继续说说变量类型相关的内容. 一.NULL补充内容 '需要注意的是,NULL不能简单通过 = 来进行比较,而必须通过 'IsNull函数来实现 ' ...

  4. 猜测的rpc负载均衡原理,基于dubbo的架构

    集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster.Directory.Router和LoadBalance.将多个服务提供方组 ...

  5. Mongodb中的 原子性 隔离性

    读写锁 Mongodb使用读写锁来来控制并发操作: 当进行读操作的时候会加读锁,这个时候其他读操作可以也获得读锁.但是不能或者写锁. 当进行写操作的时候会加写锁,这个时候不能进行其他的读操作和写操作. ...

  6. python request Payload 数据处理

    普通的http的post请求的请求content-type类型是:Content-Type:text/html; charset=UTF-8, 而另外一种形式request payload,其Cont ...

  7. Intent之跳转总结

    ) { localIntent.setAction(; ActivityManager am = (ActivityManager) context.) {) { ) { // android 5.0 ...

  8. html字体加粗标签与写法

    在html中字体加粗的标签为<b>标签,当我们使用了该标签,字体就会加粗,一般用于注明重要信息,强调文字上面写法如下 字体加粗:<b>这里的字体就会加粗</b> 效 ...

  9. Apartment 2019

    Apartment 2019 最近在学习3D建模,Apartment 2019是我的个人项目. 初步的想法是,先在网上找公寓建筑的平面图以及室内效果照片,根据这些参考图像来练习建模与渲染. 建模顺序与 ...

  10. PHP URL安全的Base64位编码

    先将内容编码成Base64结果; 将结果中的加号”+”替换成中划线“-“; 将结果中的斜杠”/”替换成下划线”_”; 将结果中尾部的“=”号全部保留; 实现 编码 function urlsafe_b ...