对UIView的hitTest: withEvent: 方法的理解

今天讲一下hitTest这个方法。

我们先看一张图:

流程图

当用户点击屏幕后,UIApplication先响应事件,然后传递给UIWindow。如果UIWindow可以响应,就开始遍历window的subviews。遍历的过程中,如果第一个view1可以响应,那就遍历view1的子视图(subviews)。如果view1不响应,就继续往下找view2,以此类推。

我们来看两个方法:
为了方便,我们将两个方法简称为A和B

方法A: - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;

方法B: - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

对View进行重写这个两个方法后,就会发现点击屏幕后,首先响应的是方法A。
如果方法A中,我们没有调用父类的这个方法,那就根据这个方法A的返回view,作为响应事件的view。(当然返回nil,就是这个view不响应)

如果方法A中,我们调用了父类的这个方法,也就是:[super hitTest:point withEvent:event];,这个时候系统就要调用方法B;通过这个方法的返回值,来判断当前这个view能不能响应消息。

如果方法B返回的是NO,那就不用再去遍历它的子视图。方法A返回的view就是可以响应事件的view。

如果方法B返回的是YES,那就去遍历它的子视图。(就是上图我们描述的那样,找到合适的view返回,如果找不到,那就由方法A返回的view去响应这个事件。)

因此总结下来:

// 返回一个view来响应事件 (我们如果不想影响系统的事件传递链,在这个方法内,最好调用父类的这个方法)
- (nullableUIView *)hitTest:(CGPoint)point withEvent:(nullableUIEvent *)event;

// 返回的值可以用来判断是否继续遍历子视图(返回的根据是触摸的point是否在view的frame范围内)
- (BOOL)pointInside:(CGPoint)point withEvent:(nullableUIEvent *)event;

本文转载自:对UIView的hitTest: withEvent: 方法的理解

你可能感兴趣的:(对UIView的hitTest: withEvent: 方法的理解)