首页 > 其他 > 详细

触摸事件的产生、传递与响应

时间:2015-11-12 23:34:09      阅读:320      评论:0      收藏:0      [点我收藏+]
在iOS系统中,发生触摸事件以后,系统会把该事件加入到一个由UIApplication管理的事件队列中。
  • 事件的分发:UIApplication会从事件队列中取出最前面的事件,并将事件分发下去处理,一般先把事件发送给应用程序的主窗口(keyWindow)
  • 主窗口会在视图层次结构中,通过hitTest方法寻找最合适的视图View来处理触摸事件,事件处理的第一步
  • 找到合适的视图View控件之后,就会调用该控件的touches方法来处理相应的事件
    • touchesBegan……
    • touchesMoved……
    • touchesEnded……
事件的传递:触摸事件的传递是从父控件传递到子控件的,以下图为例,事件的传递过程如下:
技术分享
  • 点击绿色:
    • UIApplication ->UIWindow ->白色 ->绿色
  • 点击蓝色
    • UIApplication ->UIWindow ->白色 ->橙色->蓝色
  • 点击来黄色
    • UIApplication ->UIWindow ->白色 ->橙色->蓝色->黄色
注意:如果父控件不能接收触摸事件,那么子控件就不可能接收到触摸事件
  • 不能接收触摸事件的三种情况:
    • 没有开启用户交互:userInteractionEnabled = NO
    • 控件隐藏:hidden = YES
    • 透明度太低:alpha = 0.0~0.01
如何找到最合适的控件来处理事件:
  • 判断自己能否接收触摸事件
  • 触摸点是否在自己身上
  • 按照添加子控件的顺序从后往前遍历子控件,重复上面的两步
  • 如果没有符合条件的子控件,那就默认自己是最合适处理事件的控件
  • 寻找最合适控件的底层实现
寻找最合适控件代码的底层实现:
 1 //触摸事件发生时寻找最合适的View,系统调用 hitTest: withEvent:方法找到最合适的View
 2 //当前View发生触摸事件就会调用该方法
 3 // hitTest: withEvent:方法的底层实现
 4 - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
 5     //判断触摸点是否在当前的View上,如果不在直接返回空
 6     if (![self pointInside:point withEvent:event]) {
 7         return nil;
 8     }
 9     //判断当前View是否能接收事件,不能接收事件的三种情况
10     if (self.userInteractionEnabled == NO || self.alpha <= 0.01 || self.hidden == YES) {
11         return nil;
12     }
13     //从后往前遍历子控件查找最合适的View
14     int count = (int) self.subviews.count;
15     for (int i = count -1; i >= 0; i--) {
16         //取出父控件View上的子控件
17         UIView *childV = self.subviews[i];
18         //将父控件View上的点坐标进行转换
19         CGPoint chP = [self convertPoint:point toView:childV];
20         //子控件再去查找最优View
21         UIView *fitV = [childV hitTest:chP withEvent:event];
22         //如果子控件找到就返回最合适的View
23         if (fitV) {
24             return fitV;
25         }
26     }
27     //循环结束都没找到就返回当前View作为最合适的View
28     return self;
29 }
事件处理的过程:
  • 事件产生并进行传递之后,找到最合适的控件处理事件
  • 找到最合适的视图控件之后,就会调用该控件的touches方法处理具体的事件
  • 默认情况下,touches方法调用[super touches……]方法,将事件顺着响应者链条向上传递,将事件交给上一个响应者进行处理,即调用touches……方法
事件响应者链条示意图:
  • 响应者链条:由多个响应者对象连接起来的链条
  • 作用:能清楚的看见每个响应者之间的联系,并且可以让一个事件被多个对象处理
  • 响应者对象:能处理事件的对象
技术分享
上一个响应者的判断:
  • 如果当前的控件view是控制器的view,那么控制器就是上一个响应者
  • 如果当前这个控件view不是控制器的view,那么它的父控件就是上一个响应者
响应者链条的事件传递处理:
    • 如果上一个view的控制器存在,就传递给控制器;如果控制器不存在,则将其传递给父控件
    • 在视图层次结构的最顶级视图,如果也不能处理接收到的事件或消息,则将其传递给Window对象进行处理
    • 如果window对象不能处理,则将事件或消息传递给UIApplication对象
    • 如果UIApplication也不能处理,则将事件或消息丢弃

触摸事件的产生、传递与响应

原文:http://www.cnblogs.com/JL-609/p/4960530.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!