什么是响应链和事件分发:
- 响应链:由响应者对象构成链状结构,能够响应点击、拖拽等事件
- 事件分发:屏幕捕捉到触摸事件,包装成UITouch和UIEvent对象,加入到UIApplication管理的事件队列中,然后按照一定的机制先将事件分发到keyWindow,然后按照视图结构一层层分发下去,直到找到最适合view的过程。
响应者结构图:
事件分发和响应过程:
- 从UIApplication对象分发事件开始,按照视图结构寻找最合适的响应者。调用的机制如下代码所示:
// point是该视图的坐标系上的点
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
// 1.判断自己能否接收触摸事件
if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) return nil;
// 2.判断触摸点在不在自己范围内
if (![self pointInside:point withEvent:event]) return nil;
// 3.从后往前遍历自己的子控件,看是否有子控件更适合响应此事件
NSInteger count = self.subviews.count;
for (NSInteger i = count - 1; i >= 0; i--) {
UIView *childView = self.subviews[i];
CGPoint childPoint = [self convertPoint:point toView:childView];
UIView *fitView = [childView hitTest:childPoint withEvent:event];
if (fitView) {
return fitView;
}
}
// 没有找到比自己更合适的view
return self;
}
找到最合适的view后,然后调用touchesBegan: withEvent:响应点击事件,在这个方法中,我们可以拦截事件,进行操作。代码实现如下:
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[super touchesBegan:touches withEvent:event];
}