美文网首页
手势与响应链

手势与响应链

作者: 智能音响 | 来源:发表于2019-08-10 13:32 被阅读0次

写了一个简单Demo,需要通过控制台查看打印信息。

响应链

响应链

这张图是用来说明响应链如何工作的。在HitTest已经找到最适合视图的前提下,事件从最顶部(UILabel/UITextField/UIButton)沿着实线传递。事件被处理,停止传递。整个链中都没有处理,作为无效事件被舍弃。

HitTest

当系统检查到手指触摸屏幕时,会把触摸事件加到UIApplication的事件队列中,UIApplication从事件队列中取出最新的触摸事件进行分发传递到UIWindow进行处理。 UIWindow会通过hitTest:withEvent:方法寻找触碰点所在的视图,这个过程称之为hit-test view

hit-test用来确定响应者(UIResponder)。可以简单理解为获取到响应区域的最顶层(最后添加)的可以响应的视图

hitTest方法忽略以下的视图:

1. 透明度小于0.01 alpha < 0.01

2. 视图是隐藏的 hidden=YES

3. 用户交互关闭的 userInteractionEnabled = NO

HitTest与响应链如何合作

HitTest找到响应者(UIResponder)后,UIApplication会把事件传递给响应者,触发响应链。

#0 0x000000010153990d in -[TouchView2 touchesBegan:withEvent:] 

#1 0x0000000105634240 in -[UIWindow _sendTouchesForEvent:] ()

#2 0x0000000105635bca in -[UIWindow sendEvent:] ()

#3 0x000000010561430e in -[UIApplication sendEvent:] ()

手势与HitTest

当视图上添加手势时,手势的优先级高于响应链。

当我没搞明白手势的优先级时,我有个疑惑,手势的高优先级,只影响响应链还是在hitTest时就产生作用了?

还猜测hitTest碰到手势是不是直接触发手势处理方法,都不在往下传递了。Demo中第一个例子就是为了验证这个问题。从实际处理过程看,手势不影响hitTest.

ps: hitTest会被触发两次。网上搜索这个问题,更低版本都iOS会调用3次,原因未知。

手势与响应链

既然手势不影响hitTest,只验证响应链相关都问题就好。

我验证都过程,完全是试错的过程,没有前后逻辑,直接放出结论。

1. 手势有自己单独的处理逻辑,不是依附在响应链上的。不要把手势作为响应链的角色。

2. 手势优先级高。手势识别成功会取消响应链处理。响应链即使第一时间处理事件,也无法反向取消手势处理过程。

3. UIApplication把点击事件转发响应者时,同时也转发给手势。

[UIGestureEnvironment _deliverEvent:toGestureRecognizers:usingBlock:]

这里补充我之前的错误想法:响应链传递过程中,判断当前视图有没有手势,有手势先触发手势识别,然后在调用默认touchesBegan方法。这个观点认为子视图处理完事件,父视图的手势不会被触发。与第二条结论冲突。

4. 响应点击的视图,如果既有手势也实现了touchesBegan,两个都会被触发。touches的其他方法会在手势识别后取消。在手势点击事件和touchesBegan中对参数做累加,看到看到每次点击加2.

5. 子视图父视图都有手势时,能从UITouch中获取到手势数组。手势是同时识别的,不是等到上一个手势识别完才识别下一个。数组前面的手势比后面的早识别一点时间。子视图的手势比父视图手势靠前。某一个手势识别成功,其他手势识别过程会被取消。

6. UIControl和手势叠加时,响应的是UIControl,因为UIApplication分发时,直接分发给了UIControl而不是手势。打印一下调用堆栈就能明白。没有写这个demo。

Demo介绍

第二个例子是关于手势和响应链冲突的。touchview1-touchview4 共4个视图。

TouchView1 红色,有手势

TouchView2 绿色,有手势

TouchView3 灰色,无手势

TouchView4 蓝色 ,无手势

一个视图在另一个内部,即为子视图。

验证结论1,2, 点击灰色视图。灰色视图实现了touchesBegan方法,父视图的手势还是被识别了。

验证结论3,4,点击灰色视图。number每次+2.

验证结论5,点击绿色视图。可以从log中看到gestureRecognizerShouldBegan调用时间不同。

蓝色视图,不包含手势的响应链传递。

相关文章

  • 响应链与手势

    手势冲突与响应链的关系。手势优先级更高。

  • 手势与响应链

    写了一个简单Demo,需要通过控制台查看打印信息。 响应链 这张图是用来说明响应链如何工作的。在HitTest已经...

  • iOS手势与响应者链

    这篇文章侧重于讲解手势识别、手势冲突、以及手势与响应链的关系。在处理多个手势识别场景,很容易出现手势冲突的问题,比...

  • 手势 & 响应链

    1 事件产生与传递 目的:找到可能的处理事件的Responder。传递顺序,依赖于视图树,从树根到树叶。 1.1 ...

  • IOS手势

    [TOC] ## IOS****手势 学习ios手势,先要了解响应链,ios中只要继承UIResponse对象的都...

  • 触摸,响应链,手势

    1、在iOS上,事件有多种形式 2、UIView不接收触摸事件的三种情况 二、事件处理基本方法 1、一个或多个手指...

  • 手势和响应链

    先说几条结论: 1. 系统首先根据hit-test方法,找出最佳响应者,建立响应链。 2. UIResponder...

  • iOS-添加手势(文章结尾有完整代码)

    手势,手势响应GestureRecognizer 关于手势响应IOS中封装了一个类,能响应一般手势UIGestur...

  • 给底层视图添加tap手势的穿透问题

    我们给父视图添加一个tap手势,在点击子视图的时候会响应手势. 产生这种问题的原因是子视图不能交互,响应链递归传导...

  • iOS开发经验(16)-响应机制、触摸事件、手势识别器

    目录 响应机制、触摸事件 手势识别器 手势识别与事件响应混用 1. 响应机制 在用户使用app的过程中,会产生各种...

网友评论

      本文标题:手势与响应链

      本文链接:https://www.haomeiwen.com/subject/jtxrjctx.html