美文网首页IOS面试专题iOS面试题合集(上)IOS开发知识点
iOS面试题:事件响应链是如何形成的?

iOS面试题:事件响应链是如何形成的?

作者: iOS猿_员 | 来源:发表于2020-08-21 14:40 被阅读0次

当我们触碰到屏幕的时候,整个iOS系统发生了什么呢?

这里有个思路需要转变一下,本质上,我们开发的app,里面所有的视图都是虚拟的,只是一堆代码,看起来,你的app有许多View的堆叠,而且是有层次的,你看起来触碰到了最上面的一个View,事实上屏幕只有一块啊,你触碰到的是冷冰冰的屏幕,因此第一个感知触摸事件的是操作系统,是他最先检测到屏幕上的压力,而不是你看上去触摸到的那个视图哟。

注意,这并不意味着系统会立刻处理此事件

虽然看起来app里面的控件和View是有层次的,但事实上屏幕只有一块,而且没有层次

我们如何才能构架出有层次的View呢?

苹果的办法是:画布模式,大家都见过画画,你如果在同一个地方画2笔,第二笔会覆盖第一笔,同样的,在屏幕上的同一地方有两个View,第二View会覆盖第一个View,因此在视觉上有了层次

也因此,当你触摸到屏幕上某个点的时候,其实系统并不能立刻确定你触摸的哪块View,因为多块View会有叠加、覆盖

系统会如何做呢?正如上文提到的,第一个响应的是底层系统

如上图,当我们点击View E的位置时,系统先响应,然后它会调用方法:

hitTest:withEvent:

该方法接受位置参数CGPoint,并从底层开始按照subview的顺序,测试该CGPoint在哪个View上,如果在该View上,则继续测试是否在View的subview上,对照上图,顺序如下:

1.触摸的CGPointView A上吗?在的,继续测试A的子视图View BView C

2.在View B上吗?不。在View B上吗?在,继续B的子视图View DView E

3.在View D上吗?不,且Dsubview,结束此分支

4.在View E上吗?在,Esubview,结束此分支

5.结果形成了一个链,View A -->View C -->View E

还记得吗,系统第一时间检测到了触摸,但是并不立刻处理,而是通过上述的测试,得到了一个响应链,该链的最后一个,就是逻辑上最上层的视图,也就是这次触摸的First Responder

需要注意的是,所有的响应链都是父子视图的关系哟,如果View AView CVIew E只是视觉上遮盖了,但是却不是superviewsubview的关系,则事件是不会在两者之间传递的

从底层往上的好处就是,一层层测试的过程中,响应链已经形成,当View E无法处理此事件怎么办?按照响应链往上回溯即可,一直回溯到application,也无人处理此事件,则将事件丢弃,如下图

如果First Responder不响应,则往上传给下一个View,直到传给UIApplication,依然无人响应则丢弃事件

如何处理事件?

我们获取了触摸事件,那么如何响应这个触摸呢?

其中一个是,手势识别(Gesture Recognizer): iOS提供了UITapGestureRecognizer来识别手势,它必须挂在某个View上,当某个View上发生了触摸事件,UITapGestureRecognizer就会识别该触摸,如果符合我们定义的手势,则触发一个事件

UITapGestureRecognizer *tapG =[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapClick:)];
tapG.delegate=self;
tapG.numberOfTapsRequired=2; //需要触碰2次
tapG.numberOfTouchesRequired=1;//需要一个手指
[blueView addGestureRecognizer:tapG];//把手势识别关联到blueView上

上面就是一个手势识别,当你在blueView上,单指触碰2次,就会触发tapClick:方法

以上是比较固定,好识别的手势,有些手势是没有规律可循的,比如切水果游戏中,是一指滑动切水果,角色扮演游戏中,滑动手指会使人物走动,画图板app,手指移动会留下笔画,如何定义这些手势?

事实上,我们需要在手指移动的同时就响应它,而不是等他结束了再响应,否则你的游戏就会有延时,你的画板就会等你手指离开屏幕才出现笔画,多么low的app

苹果提供了方法,让你可以实时的响应手势

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

从命名就可以看出,以上方法是何作用,顺带提一句这也是我们推荐的代码风格,从命名即可猜出用途

以上方法是UIResponder的方法,只要是他的子类,都是可以响应触摸事件的,并且按响应链顺序调用,子视图不响应,就调父视图的

哪些是UIResponder的子类呢,大家可以打开Xcode,按下shift+commond+0,打开帮助文档,可以看到每个类的继承顺序,截取几个给大家看看

看到了吗,UIViewUIViewController都是UIResponder的方法,现在想想,为啥一个View覆盖了下面的UIScrollView,你在View上滑动手指,下面的scrollView就不会滑动吗?如果这个ViewscrollView的子视图,你按住View滑动,整个scrollView都滑动了呢?

答案:覆盖的情况下,他们不是父子视图的关系,不在一条响应链上,事件并没有传给scrollView,当然不会出现滑动。如果是子视图,则在一个响应链上,View本身如果不加手势识别,并不会处理触摸事件,就会传给scrollView,而scrollView已经写好如何响应滑动,就出现滑动的效果


更多:iOS面试题
更多:《BAT面试答案文集.PDF》,获取可加iOS技术交流圈:937194184

收录:原文地址

相关文章

  • iOS面试题:事件响应链是如何形成的?

    当我们触碰到屏幕的时候,整个iOS系统发生了什么呢? 这里有个思路需要转变一下,本质上,我们开发的app,里面所有...

  • iOS 响应链

    iOS开发 - 事件传递响应链iOS 响应者链,事件的传递事件传递之响应链Cocoa Touch事件处理流程--响...

  • 深入浅出iOS事件机制

    深入浅出iOS事件机制事件传递:响应链事件传递响应链

  • 二、事件传递链和响应者链

    iOS触摸事件详解iOS开发-事件传递响应链 响应者链 UIResponser包括了各种Touch message...

  • 响应链

    iOS事件响应链中Hit-Test View的应用从iOS的事件响应链看TableView为什么不响应touche...

  • iOS基础06—--事件响应链

    iOS基础06—--事件响应链 移动应用的最大特性就是响应用户交互操作,那么iOS系统是如何去响应一个简单的点击事...

  • iOS面试题:说说响应链

    原文:iOS面试题大全 当事件发生的时候,响应链首先被发送给第一个响应者(往往是事件发生的视图,也就是用户触摸屏幕...

  • iOS中对于响应链的理解

    对于响应链的理解: 在IOS中,有响应者链对事件进行响应,所有的响应类都是UIResponder的子类,响应者链是...

  • iOS响应者链

    参考好文 iOS开发-事件传递响应链,用运行时分析 iOS事件传递:响应者链[译] http://www.jian...

  • iOS开发:浅谈响应链与事件传递

    响应链: 第一响应者到application对象的一系列响应者形成的链条 如何寻找第一响应者: 1、当iOS程序发...

网友评论

    本文标题:iOS面试题:事件响应链是如何形成的?

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