美文网首页
面试复习-事件响应链总结

面试复习-事件响应链总结

作者: 云无心 | 来源:发表于2021-04-20 13:31 被阅读0次

首先参考响应者链条 https://www.jianshu.com/p/c294d1bd963d

系统响应

  1. 首先 屏幕接收到点击后,IOKit会进行事件捕捉
  2. 而后通过 mach port传递给SpringBoad进程
  3. SpringBoard进程因接收到触摸事件,触发了主线程runloop的source1事件源的回调
  4. 如果此时在桌面,则交给桌面系统去消耗该事件
  5. 如果此时在app前台,则通过IPC(进程通信)传给app进程

APP响应

  1. 通过 mach port收到SpringBoad的触摸事件,主线程runloop被唤醒,触发source1回调
  2. source1回调触发soirce0回调,将触摸事件封成UIEvent事件
  3. source0将事件添加到UIApplication对象的队列中,开始寻找最佳响应者hit-testing
  4. 寻找到最佳响应者后,开始事件的响应在响应链中的传递和响应
  5. 触摸事件要么被某个响应对象捕获后释放,要么无法找到响应对象后释放

hit-Testing

  1. UIApplication 通过 调用UIWindow的 hitTest:withEvent: 传递给UIWindow,依次从后往前遍历子视图传递
  2. 过程
    1. 判断是否可交互
      • 不允许交互:userInteractionEnabled = NO
      • 隐藏:hidden = YES 如果父视图隐藏,那么子视图也会隐藏,隐藏的视图无法接收事件
      • 透明度:alpha < 0.01 如果设置一个视图的透明度<0.01,会直接影响子视图的透明度。alpha:0.0~0.01为透明。
    2. 判断是否在视图中 if ([self pointInside:point withEvent:event] == NO) return nil;
    3. 判断是否在子视图中 CGPoint childP = [self convertPoint:point toView:childView];
      UIView *fitView = [childView hitTest:childP withEvent:event];
    4. 重写父视图 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 可以实现超出点击

事件响应

  1. 事件的最佳响应者是 hit-tested view,他可以独吞事件 也可以往后传递
  2. 不操作默认往下分发,通过nextResponder
  3. 在 touchesMoved: withEvent: 是否调用父类同名方法决定是否往下分发

事件优先级 UIResponder、UIGestureRecognizer、UIControl

UIResponder 和 UIGestureRecognizer

  1. 如果成功识别了 UIGestureRecognizer 则 优先进行 手势,而中止 hit-tested view的 UIResponder 过程。
  2. 触摸状态变化 的 begin 先发送到 手势 再 hit-tested
  3. 顺序为 手势begin —— hit-test begin—— 手势识别成功——手势end ——hit-test cancel
  4. 属性:cancelsTouchesInView 。默认YES,代表手势成功后,屏蔽响应链的响应
  5. 属性:delaysTouchesBegan 。默认NO,代表在手势识别期间不会调用 hit-test begin,move等
  6. 属性:delaysTouchesEnded 。默认YES,代表手势失败后,会延迟0.15s调用响应者的 touchesEnded:withEvent:,若NO,立即调用

UIControl

- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(nullable UIEvent *)event;
- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(nullable UIEvent *)event;
- (void)endTrackingWithTouch:(nullable UITouch *)touch withEvent:(nullable UIEvent *)event;
- (void)cancelTrackingWithEvent:(nullable UIEvent *)event;

这几个方法是在 touch 系列里面调用的

  1. UIControl会阻止父视图上的手势识别器行为,也就是UIControl处理事件的优先级比UIGestureRecognizer高,但前提是相比于父视图上的手势识别器。
  2. UIControl比其父视图上的手势识别器具有更高的事件响应优先级。
  3. 准确地说只适用于系统提供的有默认action操作的UIControl,例如UIbutton、UISwitch等的单击

UIResponser
一:响应者链 UIResponser包括了各种Touch message 的处理,比如开始,移动,停止等等。常见的 UIResponser 有 UIView及子类,UIViController,APPDelegate,UIApplication等等。
回到响应链,响应链是由UIResponser组成的,那么是按照哪种规则形成的。

A: 程序启动 UIApplication会生成一个单例,并会关联一个APPDelegate。APPDelegate作为整个响应链的根建立起来,而``UIApplication会将自己与这个单例链接,即UIApplication的nextResponser(下一个事件处理者)为APPDelegate`。

B:创建UIWindow 程序启动后,任何的UIWindow被创建时,UIWindow内部都会把nextResponser设置为UIApplication单例。UIWindow初始化rootViewController,rootViewController的nextResponser会设置为UIWindow

C:UIViewController初始化 loadView, VC的view的nextResponser会被设置为VC.

D:addSubView addSubView操作过程中,如果子subView不是VC的View,那么subView的nextResponser会被设置为superView。如果是VC的View,那就是 subView -> subView.VC ->superView如果在中途,subView.VC被释放,就会变成subView.nextResponser = superView

相关文章

  • 面试复习-事件响应链总结

    首先参考响应者链条 https://www.jianshu.com/p/c294d1bd963d[https://...

  • 【iOS小结】事件和响应者链

    之前面试问到一个响应者链的问题,结果让我很尴尬。于是,就想着写篇关于响应链的总结。当然,响应者链也包含事件、响应者...

  • 2020-03-02

    通过网络搜寻和自己总结经历找了一些IOS面试经常被问道的问题: 1.搞清楚touch事件的传递(事件的响应链) 事...

  • iOS 响应链

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

  • UIControl && UIGestureRecognizer

    事件传递和响应链 一. 事件传递 二.响应链 响应链: 三.UIGestureRecognizer 四.cance...

  • 深入浅出iOS事件机制

    深入浅出iOS事件机制事件传递:响应链事件传递响应链

  • 响应链和事件分发

    什么是响应链和事件分发: 响应链:由响应者对象构成链状结构,能够响应点击、拖拽等事件 事件分发:屏幕捕捉到触摸事件...

  • IOS开发 事件响应链

    本节学习内容: 1.事件响应链的概念 2.事件响应链的传递机制 3.事件响应链的应用 响应顺序 Subview>M...

  • iOS知识收集

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

  • 响应链总结梳理与应用

    响应链总结梳理与应用 App使用响应者对象接收和处理事件,响应者对象是任何UIResponder的实例。UIRes...

网友评论

      本文标题:面试复习-事件响应链总结

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