美文网首页
iOS事件传递+响应者链条(responseChain)模拟

iOS事件传递+响应者链条(responseChain)模拟

作者: mrChan1234 | 来源:发表于2018-08-16 11:40 被阅读0次

在前面的文章中,我提到了事件传递和响应的U型传递,这里我们通过一个demo模拟来具体查看他的传递和响应顺序,例如点击一个按钮,iOS的后面具体做了些什么呢?

首先我们看下图:


repsonseChain.png

我们点击蓝色的view,系统后面做了些什么操作呢?前面我们说了,我们用手指点击屏幕的时候,硬件接收到了这种touch操作,然后和iOS系统打交道,以source0的形式通知到UIApplication的currentRunLoop(其实也就是mainRunloop),runloop接收到source0事件,将该事件封装成一些对象(这些对象包含事件的一些信息,比如:UITouch、UIEvent)
我们可以通过打断点看到这个调用过程:


source0.png
系统会把该事件加入UIApplication管理的事件队列中去,这个队列是先进先出的,然后UIApplication会从事件队列中去取出最前面的事件,并将事件分发下去以便处理:
以我们这个例子来看,当我点击蓝色view,他的事件传递从最上层的UIAplication逐次向下传递,我们通过下面的代码来模拟:
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    [super touchesBegan:touches withEvent:event];
}

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    NSLog(@"查找到了%@",NSStringFromClass([self class]));
    // 1.判断下自己能否接收事件
    if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) return nil;
    // 2.判断下点在不在当前控件上
    if ([self pointInside:point withEvent:event] == NO) return  nil; // 点不在当前控件
    int count = (int)self.subviews.count;
    for (int i = count - 1; i >= 0; i--) {
        UIView *childView = self.subviews[i];
        // 把当前坐标系上的点转换成子控件上的点
        CGPoint childP =  [self convertPoint:point toView:childView];
        UIView *actionView = [childView hitTest:childP withEvent:event];
        if (actionView) {
            return actionView;
        }
    }
    // 4.如果没有比自己合适的子控件,最合适的view就是自己
    return self;
}

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    return CGRectContainsPoint(self.bounds, point);
}

其实系统会逐次递归调用以上的两个方法,直至找到最合适的view

(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

上面这个方法判断响应事件的point是否包含在自己的frame内部

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

以上这个方法来查找最合适的处理的view,


event distribute desc.png

断点打印如下:


example.png

找到最合适的view(即蓝色的view)以后,这个view会将Touch和Event向上传递:
我们可以通过模拟调用下面这个方法来模拟:

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    [super touchesBegan:touches withEvent:event];
}

断点截图如下:


event distribute.png breakPoint stack.png

最终事件回到了最上层的UIApplication,在APPDelegate里重写touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event ,我们会发现断点走到这里来了:


event.png

当然了,iOS系统后面做的一些处理,我们可以在clang命令里面查看C ++源码(这些操作是很复杂的,这里我个人能力有限,请大家自行去研究,菜逼如我是不能给大家分析的),这里简单的模拟下这个过程,意在让读者理解事件传递和响应的顺序和过程,结合前面我写的那片基础点的文章来看, 希望对您理解事件传递和响应有所帮助,写的不对的地方希望读者不吝赐教,如果您觉着对您有帮助,左下角赞我一波啊!🤗

相关文章

  • iOS事件传递+响应者链条(responseChain)模拟

    在前面的文章中,我提到了事件传递和响应的U型传递,这里我们通过一个demo模拟来具体查看他的传递和响应顺序,例如点...

  • iOS 响应链

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

  • 01进阶之路-UI视图

    1. 事件传递机制和响应者链条 学习链接 事件传递机制iOS中的事件可以分为3大类型 1 触摸事件 2 加速计...

  • 响应者链(Responder Chain)

    响应者链条主要分为两部分:事件的传递链条和事件的响应链条。 1、事件的传递链条: 当屏幕发生触摸事件后,系统会将事...

  • Response chain

    事件传递、响应者链条、hitTest和pointInside的使用

  • iOS的事件传递: 响应者链条

    一. iPhone操作系统下的事件 事件是被发送到应用程序中反应用户操作的对象。当用户触发一个事件时,UI...

  • iOS 事件传递和响应者链条

    事件的传递 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中。 UIAppli...

  • iOS事件传递及响应者链条

    在ios中,事件用UIEvent类来表示,当一个事件发生时,系统会搜集的相关事件信息,创建一个UIEvent对象,...

  • iOS事件传递及响应者链条

    这里, 将带你解析"从你的手指触摸屏幕, 到App作出响应"这段历程中究竟发生了什么事. 什么是事件? iOS中事...

  • iOS-事件传递,响应者链条

    原文地址:https://www.jianshu.com/p/0892b08367cf[https://www.j...

网友评论

      本文标题:iOS事件传递+响应者链条(responseChain)模拟

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