美文网首页
iOS开发:浅谈响应链与事件传递

iOS开发:浅谈响应链与事件传递

作者: yangfei02821 | 来源:发表于2020-07-03 11:00 被阅读0次

    响应链:

    第一响应者到application对象的一系列响应者形成的链条

    如何寻找第一响应者:

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

    hitTest:withEvent:的处理流程

    1、首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内;
    2、若返回NO,则hitTest:withEvent:返回nil;
    3、若返回YES,则向当前视图的所有子视图(subviews)从上往下发送hitTest:withEvent:消息
    4、若有子视图返回非空对象,则hitTest:withEvent:方法返回此对象,处理结束;
    5、如所有子视图都返回非,则hitTest:withEvent:方法返回自身(self)。

    hitTest:withEvent:方法的伪代码

    //返回最适合处理事件的视图,最好在父视图中指定子视图的响应
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        if (!self.userInteractionEnabled || !self.hidden || self.alpha <= 0.01) {
            return nil;
        }
        
        if ([self pointInside:point withEvent:event]) {
            
            for (UIView *subView in [self.subviews reverseObjectEnumerator]) {
                CGPoint subPoint = [subView convertPoint:point fromView:self];
                
                UIView *bestView = [subView hitTest:subPoint withEvent:event];
                if (bestView) {
                    return bestView;
                }
            }
            return self;
        }
    
        return nil;
    }
    

    事件的响应流程

    事件的响应流程

    1.首先通过 hitTest:withEvent: 确定第一响应者,以及相应的响应链
    2.判断第一响应者能否响应事件,如果第一响应者能进行响应则事件在响应链中的传递终止。如果第一响应者不能响应则将事件传递给父试图或者控制器
    3.如果事件继续上报至UIWindow并且无法响应,它将会把事件继续上报给UIApplication
    4.如果事件继续上报至UIApplication并且也无法响应,它将会将事件上报给其Delegate
    5.如果最终事件依旧未被响应则会被系统抛弃

    借鉴:
    iOS开发:浅谈响应链与事件传递

    相关文章

      网友评论

          本文标题:iOS开发:浅谈响应链与事件传递

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