1. UIView(事件传递与视图响应链)和CALayer

2020-06-22  本文已影响0人  如果大雨落下

单一职责原则

1. UIView可以响应事件

以touch事件为例,view接收到touch事件
图片.png
  1. 用户触摸屏幕时,UIKit会生成UIEvent对象来描述触摸事件。对象内部包含了触摸点坐标等信息
  2. 通过- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event和- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event; 来一层层的查找响应事件的Responder
  3. 如果View 的 userInteractionEnabled = NO,enabled = NO( UIControl ),或者 alpha <= 0.01, hidden = YES 直接返回 nil(不再往下判断)。(view不响应事件)
  4. 如果触摸点不在 view 中,直接返回 nil。通过 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
  5. 如果触摸点在 view 中,逆序 遍历它的子 View ,重复上面的过程,如果子View没有subView了,那子View就是hit-TestView。
  6. 如果 view 的 子view 都返回 nil(都不是 hit-TestVeiw ),那么返回自身(自身是 hit-TestView )。
递归循环上述 2-6 ,找出hit-TestView,该view就成为firstResponder,用来响应事件,如果view响应不了,就往上找寻nextResponder,具体找寻过程如图所示:
图片.png
  1. 通过UIApplication和UIWindow对象将事件Event分发给响应的对象,touch事件就是hit-TestView,其他事件就是firstResponser,如果响应者处理不处理,通过responder chain交给上一级处理,一级一级下传,如果UIapplicaiton处理不了,事件就会被丢弃
  2. 事件怎么往上一级回传,touch事件是通过touchbegin,touchmove方法,调用super一级一级回传,当一个view或者controller里面没有重写touch事件,那么这个事件就会一直传递下去,直到UIApplication,这也就是事件往上冒泡的原理,如果重写了,事件就是被拦截掉,nextResponser就不会在响应这一事件
    如果当前的 View 有添加手势,那么直接响应相应的事件,不会继续向下寻找了,因为手势比响应链拥有更高的优先级
  3. UIControl 能直接响应事件,是因为重写了touchbeign,方法,uiview默认不响应事件,没有重写

2. CALayer继承自NSObject,不能响应事件

理解frame

http://www.cocoachina.com/articles/7498

View-Layer 协作

https://objccn.io/issue-12-4/

上一篇 下一篇

猜你喜欢

热点阅读