工作生活

iOS事件传递响应机制

2019-07-01  本文已影响0人  山有木枝壮

iOS系统架构一共分为四层,分别是Cocoa Touch层(触摸层)、Media(媒体层)、Core Service(媒体服务器层)和Core OS(核心操作系统层) ,我们常用的UIKit组件就是位于Cocoa Touch层。

事件传递与响应是分不开的,用户点击屏幕之后产生事件,最终由某个view捕获,并且经过响应链进行响应。

如下图


事件的传递

事件传递主要有两个方法决定某个view是不是该事件的响应者。
1、hitTest方法

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

该方法主要用递归的方式从后向前遍历加入到视图中的view
2、pointInside方法
用来判断点击事件是否在某个view上

遍历视图中所有view及其子view,经过hitTest和pointInside方法,就可以找出响应该事件的view。
通过pointInside方法,我们可以很轻松的扩大button的点击区域

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    NSLog(@"%s", __func__);
    //扩大它的响应范围
    CGRect frame = [self getScaleFrame];
    return CGRectContainsPoint(frame, point);
    
   //  return [super pointInside:point withEvent:event];
}

- (CGRect)getScaleFrame {
    CGRect rect = self.bounds;
    if (rect.size.width < 40.f) {
        rect.origin.x -= (40-rect.size.width)/2;
    }
    if (rect.size.height < 40.f) {
        rect.origin.y -= (40-rect.size.height)/2;
    }
    rect.size.width = 40.f;
    rect.size.height = 40.f;
    return rect;
}

整个事件传递机制步骤如下:
1、点击屏幕,产生触摸事件之后,放入UIApplication的队列中。
2、从队列中取出最前面的事件,传递给keyWindow,从父控件传递到子控件
3、寻找最合适的view(怎样找?)

通过上面的步骤,我们只是找到可以可以响应该事件的视图,那么视图是如何一步一步通过响应链传递的?
响应者链

响应者对象:能处理事件的对象,也就是继承自UIResponder的对象
作用:能很清楚的看见每个响应者之间的联系,并且可以让一个事件多个对象处理。

如何判断上一个响应者

1> 如果当前这个view是控制器的view,那么控制器就是上一个响应者
2> 如果当前这个view不是控制器的view,那么父控件就是上一个响应者

响应者链的事件传递过程:

1>如果当前view是控制器的view,那么控制器就是上一个响应者,事件就传递给控制器;如果当前view不是控制器的view,那么父视图就是当前view的上一个响应者,事件就传递给它的父视图
2>在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理
3>如果window对象也不处理,则其将事件或消息传递给UIApplication对象
4>如果UIApplication也不能处理该事件或消息,则将其丢弃

补充

事件在整个iOS系统架构的传递


事件流程图

参考:
1、事件响应原理
2、iOS事件传递和响应机制

上一篇 下一篇

猜你喜欢

热点阅读