转眼,好几个月没有写一篇文章了,虽然中间经历了一次春节,但这应该不是借口😆
言归正传,今天记录一下之前学习的时间从产生到响应的这个过程.以一个手指的点击事件为例.(注意,本篇只是概括事件响应的流程,可能不够详细)
- 1.当点击事件发生后,系统会将事件加入到一个UIApplication管理事件的队列中
- 2.UIApplication 会从事件队列中取出最前面的事件,并将事件分发下去,通常先发送给应用程序的主窗口(KeyWindow)
- 3.主窗口会在视图层次结构中找到一个最合适的视图来处理点击事件,这是事件处理的第一步(重要!)
- 4.调用最适合view的touches方法去处理事件
- 5.如果最适合的view不对改事件做处理,默认传给响应者链条的上一个响应者,接着调用上一个响应者的touches方法(如果一直没有响应者处理事件传回到UIApplication,改事件被丢弃)
从这个流程中,不免抛出了两个个问题:
问题一 : 寻找最适合的view
- 1.首先查看自己能否接收事件(如何判断一个控件是否能接收事件,下面有介绍)
- 2.判断点是否在自己的身上(如何判断点在不在自己身上,下面有介绍)
- 3.从后往前(从subviews.lastObject开始寻找)遍历子空间,重复1,2步
- 4.如果没有符合的字控件,自己就是最适合的view
问题二 : 判断上一个响应者
- 1.判断当前view是否为控制器的view,如果是控制器的viwe,那么控制器就是上一个响应者.
- 2.如果不是控制器的view,那么,父控件就是上一个响应者.
从问题一中,又抛出了这样两个问题:
问题一 : 如何判断一个控件是否能接收事件
一般view都能接收事件,但是有下面几种情况,view不能接收事件:
- 1.父控件不能接收事件
- 2.UserInterfacetionEnable = NO; 也就是没有打开用户交互
- 3.view.hidden = YES;
- 4.view.alpha = 0;
问题二 :如何判断点在不在自己身上
view内部通过下面的方法的返回值判断,返回YES则点在自己身上,返回NO则点不在自己身上(注意,调用下面的方法,必须保证传入的point属性与view在同一坐标系)
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
总结:事件产生之后,从UIApplication层往上(有的也叫从下,我习惯说往上 - - #)传递寻找最适合的view.找到最适合的view之后,查看最适合的view是否重写了touches方法处理事件,如果没有重新touches方法,则从最适合的view开始,查看上一个响应者的touches方法是否处理事件,如果一直传回到UIApplication,则事件被丢弃.
假设现在:
keyWindow.rootViewController = vc1;
[vc1 addSubView:view1];
有一个点击事件,点在了view1所在的区域.而view1,vc1都没有重写touches方法
寻找到最适合的view : UIApplication->keyWindow->vc1.view->view1
事件处理 : view1(touches)->vc1.view(touches)->vc1(touches)->keyWindow(touches)->UIApplication
网友评论