美文网首页
iOS-详解事件传递和响应者链

iOS-详解事件传递和响应者链

作者: 搬砖人666 | 来源:发表于2019-11-29 18:38 被阅读0次

事件响应

一、事件的分发和传递(确定事件的第一响应者):

1.当iOS程序中发生触摸事件后,系统会将事件加入到UIApplication管理的一个任务队列中
2.UIApplication将处于任务队列最前端的事件向下分发。即UIWindow。
3.UIWindow将事件向下分发,即UIView。
4.UIView首先看自己是否能处理事件,触摸点是否在自己身上。如果能,那么继续寻找子视图。
5.遍历子控件,重复以上两步。
6.如果没有找到,那么自己就是事件处理者。如果
7.如果自己不能处理,那么不做任何处理。
其中 UIView不接受事件处理的情况主要有以下三种
1)alpha <0.01
2)userInteractionEnabled = NO(中间一层userInteractionEnabled = NO,则事件响应者链受阻)
3.hidden = YES.
第4步中UIView如何判断触摸点在自己身上呢?

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
    return [super pointInside:point withEvent:event];
}

return YES,则点在自己身上,遍历子视图寻找下一层目标View,return NO,则此view和此view 的子view都不响应事件,不会成为事件的第一响应者。

遍历子视图,寻找下一层目标view:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    // 1.如果控件不允许与用用户交互,那么返回nil
    if (self.userInteractionEnabled == NO || self.alpha <= 0.01 || self.hidden == YES){
        return nil;
    }
    // 2. 如果点击的点在不在当前控件中,返回nil
    if (![self pointInside:point withEvent:event]){
        return nil;
    }
    // 3.从后往前遍历每一个子控件
    for(int i = (int)self.subviews.count - 1 ; i >= 0 ;i--){
        // 3.1获取一个子控件
        UIView *childView = self.subviews[i];
        // 3.2当前触摸点的坐标转换为相对于子控件触摸点的坐标
        CGPoint childP = [self convertPoint:point toView:childView];
        // 3.3判断是否在在子控件中找到了更合适的子控件(递归循环)
        UIView *fitView = [childView hitTest:childP withEvent:event];
        // 3.4如果找到了就返回
        if (fitView) {
            return fitView;
        }
    }
    // 4.没找到,表示没有比自己更合适的view,返回自己
    return self;
}

子view会重复以上两个方法,最后的一个响应者即为第一响应者。

二、确定响应者后进入事件处理流程:

第一响应者无响应且无任何操作,则事件被废弃
第一响应者响应事件,事件处理完成
如下图点击屏幕中的view2,则
AppDelegate --> window --> rootViewController --> contentView --> view2
所组成的链条就是事件响应者链。
整个过程详见下图1:
注意一点:点击屏幕后不是点击了屏幕中的view,而仅仅是点击了屏幕,然后生成了一个event包含了点击坐标的信息,iOS系统会接收到点击事件交给当前前台的UIApplication继续往下处理,要是直接点击到view了还要什么响应者链

视图层级 图1
改变响应者链

某个事件响应者链中View的pointInSide方法返回NO,则此view不响应事件,此view的上一响应者即为第一响应者。由下图2可看出响应链变小,此时点击view1、view2、contentView的第一响应者都是rootViewController。

图2

手动更改某个view的nextResponder也会改变事件响应者链,例如viewController的默认view的nextResponder指向了viewController,viewController上的View的点击事件全部ViewController中响应,类似图2中的contentView的点击事件全部在rootViewController(contentView的nextResponder)中响应

欢迎留言,共同进步。

参考资料:
1、iOS-事件传递,响应者链条及常见面试题:https://www.jianshu.com/p/0892b08367cf
2、iOS 响应者及响应者链:https://www.jianshu.com/p/89d20caabf41
3、UIView的hitTest和pointInside方法:https://www.jianshu.com/p/c87de31b3985
4、hitTest和pointInside方法你真的熟吗?:https://juejin.im/entry/59e07e616fb9a04528458048
5、iOS事件响应链(通俗易懂篇):https://blog.csdn.net/u013602835/article/details/79986819

相关文章

  • iOS 响应链

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

  • 二、事件传递链和响应者链

    iOS触摸事件详解iOS开发-事件传递响应链 响应者链 UIResponser包括了各种Touch message...

  • iOS-详解事件传递和响应者链

    事件响应 一、事件的分发和传递(确定事件的第一响应者): 1.当iOS程序中发生触摸事件后,系统会将事件加入到UI...

  • iOS知识收集

    1. 响应者链 1.1 Cocoa Touch事件处理流程--响应者链 1.2 事件传递之响应链 多线程 http...

  • 外部较好的学习主题

    1、关于响应者链和事件传递https://segmentfault.com/a/11900000150606032...

  • iOS UI事件传递与响应者链

    iOS UI事件传递与响应者链 响应者链 响应者对象:继承自UIResponder的对象称之为响应者对象。UIAp...

  • dailyLearning -- 响应者链

    响应者对象介绍 什么是响应者链 事件响应流程(事件的产生和传递) 怎么寻找最合适的 view 应用 在runLoo...

  • iOS 事件传递机制

    事件传递机制 响应者链的事件传递过程:如果当前view是控制器的view,那么控制器就是上一个响应者,事件就传递给...

  • iOS 响应者链

    响应者链 响应者链是一个响应者的连接序列,事件或者动作消息依次传递,它允许响应者把事件处理的职责转交给其他更高层次...

  • 响应者链

    响应者链 响应者链是一个响应者的连接序列,事件或者动作消息依次传递,它允许响应者把事件处理的职责转交给其他更高层次...

网友评论

      本文标题:iOS-详解事件传递和响应者链

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