UIView 点击事件传递

2021-07-15  本文已影响0人  helinyu
  • (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event; // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system
    返回一个UIView, 用来寻找最终哪一个视图来响应这个事件。
  • (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event; // default returns YES if point is in bounds
    用来判断点击的位置是否在视图范围内, 如果在就返回YES。

这个过程,使用了递归以及使用了责任链的设计模式

1、 为什么hitTest以及pointInside方法, 在触发了一次之后调用了两次?
目前查找到的资料是校验精确的位置。

2、 我们看到的是先调用hitTest在调用pointInside 这个方法;

点击事件的事件传递过程:
1)当屏幕产生触摸事件的时候, 消息循环runloop会接收到事件将事件加入到UIApplication的管理的时间队列中, UIApplication 从最前面的时间队列中取出时间进行分发,首先传给UIWindow。
2) UIWindow 会调用hitTest:withEvent: 方法, 找到此次触摸时间初始带你所在的视图
3)hitTest:withEvent: 中回调pointInside:withEvent: 方法判断当前的触摸点是否在要命中的范围内。 有就返回YES , 没有就返回NO。
4) 然后子view继续遍历它自己的子views

使用的倒叙的方式来遍历子视图, 也就是说最后添加的子视图会最先遍历, 在每个视图中都会去调用它的hitTest:withEvent: 方法,, 可以理解为是一个递归调用。

调用hitTest:withEvent:时,会先判断当前视图(alpha > 0.01 ishidden == NO && isUserInteractionEnabled = YES )这些都成立,才以倒序遍历调用 hitTest 方法 返回相应的视图

借用一张图片, 勿怪
上一篇下一篇

猜你喜欢

热点阅读