浅析iOS中事件的产生与响应过程

想要学习事件的产生与响应过程首先要了解什么是响应者对象,什么是响应者链条

响应者对象:继承了UIResponder的对象称之为响应者对象,也就是能处理事件的对象。

响应者链条:是由多个响应者对象连接起来的链条。

其次,并不是所有的控件都可以接收事件,在以下五种情况下控件不能接收事件:

  1. 不接收用户交互时不能够处理事件

    userInteractionEnabled = NO;
    注意:UIImageView的userInteractionEnabled默认就是NO

  • 当一个控件隐藏的时候不能够接收事件

    Hidden = YES

  • 当一个控件为透明的时候也不能够接收事件

    alpha <= 0.01;

  • 父控件不能接收事件,那么子控件也不能接收事件

  • 子控件超出父控件的大小


事件是怎样产生与传递的?

当用户点击屏幕后会产生一个触摸事件,系统会将该事件加入到一个由UIApplication管理的事件队列中。UIApplication会从事件队列中取出最前面的事件,并将事件传递给先发送事件给应用程序的主窗口以便处理,主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件。

事件传递示例

怎么寻找处理事件最合适的视图 view ?

  1. 先判断自己是否能够接收触摸事件,如果能再继续往下判断;
  • 再判断触摸的当前点在不在自己的身上;
  • 如果在自己身上,它会从后往前遍历子控件,遍历出每一个子控件后,重复前面的两个步骤;
  • 如果没有符合条件的子控件,那么它本身就是要寻找的最适合的View。

在寻找最合适的视图 view 中,需要使用到 hitTestPointInside 两个方法。

hitTest 方法与 PointInside 方法

  1. hitTest 方法

    •  -(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
      
      • 作用:寻找最适合的View
      • 参数:当前手指所在的点,产生的事件
      • 返回值:返回谁,谁就是最适合的View
      • 只要传递给一个控件时,就会调用这个控件的 hitTest 方法
  • PointInside 方法

    • -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
        return YES;
       }
      
      • 作用:判断point在不在方法调用者上
      • point:必须是方法调用者的坐标系
      • hitTest方法底层会调用这个方法,判断点在不在控件上
  • hitTest 方法的底层实现

    ① 判断当前控件能不能接收事件

    if(self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01)  {
        return  nil;
    }
    

    ② 判断触摸点在不在当前的控件上

    if(![self pointInside:point withEvent:event]) {
        return nil;
    }
    

    ③ 从后往前遍历自己的子控件

    int count = (int)self.subviews.count;
    for (int i = count - 1; i >= 0;i-- ) {
        
     UIView *childV = self.subviews[i];
     //把当前坐标系上的点转换成子控件坐标系上的点
     CGPoint childP = [self convertPoint:point toView:childV];
     //判断自己的子控件是不是最适合的View
     UIView *fitView = [childV hitTest:childP withEvent:event];
     //如果子控件是最适合的View,直接返回
     if (fitView) {
          return  fitView;
      }
     //否则自己就是最适合的View
     return self;
    }
    

事件产生、传递与响应的完整过程

  1. 当用户点击屏幕后会产生一个触摸事件,系统会将该事件加入到一个由UIApplication管理的事件队列中;
  2. UIApplication会从事件队列中取出最前面的事件,并将事件传递给先发送事件给应用程序的主窗口以便处理;
  3. 主窗口会调用 hitTest 方法寻找最适合的视图控件,找到后就会调用视图控件的 touches 方法来做具体的事情;
  4. 当调用 touches 方法,它的默认做法会将事件顺着响应者链条往上传递;
  5. 传递给上一个响应者,接着就会调用上一个响应者的touches方法。


    响应者链条示意图

如何寻找上一个响应者?

  1. 如果当前的View是控制器的View,那么控制器就是上一个响应者
  2. 如果当前的View不是控制器的View,那么它的父控件就是上一个响应者
  3. 在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理
  4. 如果window对象也不处理,则其将事件或消息传递给UIApplication对象
  5. 如果UIApplication也不能处理该事件或消息,则将其丢弃
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容