美文网首页
iOS事件传递过程以及响应链

iOS事件传递过程以及响应链

作者: Queen_BJ | 来源:发表于2020-09-04 16:00 被阅读0次
    • 响应者
      响应者为响应事件的UIResponder子类对象,如UIButton、UIView等
    • 响应链
      响应链是由链接在一起的响应者(UIResponse子类)组成的。
    • 事件传递
      获得响应链后,将事件由第一响应者往application传递的过程

    事件的传递过程

    • 触摸事件的传递是从父控件传递到子控件
    • 如果父控件不能接受触摸事件,那么子控件就不可能接收到触摸事件

    1、当iOS程序发生触摸事件后,系统会利用Runloop将事件加入到UIApplication的任务队列中,具体过程可以参考深入理解RunLoop
    2、UIApplication分发触摸事件到UIWindow,然后UIWindow依次向下分发给UIView
    3、UIView调用hitTest:withEvent:方法看看自己能否处理事件,以及触摸点是否在自己上面。
    4、如果满足条件,就遍历UIView上的子控件。重复上面的动作。
    5、直到找到最顶层的一个满足条件(既能处理触摸事件,触摸点又在上面)的子控件,此子控件就是我们需要找到的第一响应者。

    // 此方法返回的View是本次点击事件需要的最佳View
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
    
    // 判断一个点是否落在范围内
    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
    //返回最适合处理事件的视图,最好在父视图中指定子视图的响应
    
    // 因为所有的视图类都是继承BaseView
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
       // 1.判断当前控件能否接收事件
       if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) return nil;
       // 2. 判断点在不在当前控件
       if ([self pointInside:point withEvent:event] == NO) return nil;
       // 3.从后往前遍历自己的子控件(先加的控件在下面,后加的在上面,为了让最上层的响应者最先响应事件)
       NSInteger count = self.subviews.count;
       for (NSInteger i = count - 1; i >= 0; i--) {
           UIView *childView = self.subviews[I];
           // 把当前控件上的坐标系转换成子控件上的坐标系
        CGPoint childP = [self convertPoint:point toView:childView];
          UIView *fitView = [childView hitTest:childP withEvent:event];
           if (fitView) { // 寻找到最合适的view
               return fitView;
           }
       }
       // 循环结束,表示没有比自己更合适的view
       return self;
       
    }
    

    事件的传递和响应的区别:
    事件的传递是从上到下(父控件到子控件)
    事件的响应是从下到上(顺着响应者链条向上传递:子控件到父控件)

    事件的响应

    • 事件响应会先从底层最合适的view开始,然后随着上一步找到的链一层一层响应touch事件。默认touch事件会传递给上一层。
    • 如果到了viewcontroller的view,就会传递给viewcontroller。如果viewcontroller不能处理,就会传递给UIWindow
    • 如果UIWindow无法处理,就会传递给UIApplication
    • 如果UIApplication无法处理,就会传递给UIApplicationDelegate。
    • 如果UIApplicationDelegate不能处理,则会丢弃该事件

    可参考一

    可参考二

    可参考三

    图式好理解

    相关文章

      网友评论

          本文标题:iOS事件传递过程以及响应链

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