IOS事件传递机制

序言

我们的app项目界面往往是一个父视图包含多个子视图,那么当我们点击屏幕的时候,系统是怎么判断由哪个视图来处理这个点击事件呢?


响应链传递

这里先介绍一个方法
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;    // default returns YES if point is in bounds
当这个方法返回YES的时候说明这个对象响应用户操作,返回NO就不响应。
blob.png
如图,B,D是A视图的子视图,C是B的子视图
系统是通过反向查找来找到最终处理事件的视图的
当我们点击C视图的时候
1,A视图遍历它的子视图B,D是否响应当前事件(通过上面所讲的方法),显然点击范围在B视图的bounds内,所以B返回YES,D返回NO。
2,B视图再遍历它的子视图,点击事件在C范围内,所以C返回YES
3,C没有子视图,所以系统会判定C为最终响应者。
执行完上面步骤后,
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;    // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system
1,系统会通过上面的方法询问C由谁来处理这个事件响应,默认是返回self(但是UIViewcontroller返回的是视图控制器)
2, 系统会查找C里面的处理响应事件的方法(例如touchBegin:wirhEvent,详见UIResponser讲解)
3,如果C里面没有实现相应的处理方法,这时候并不会把当前事件丢掉,而是会到C的上一级响应者,也就是B视图里面寻找相应的方法,B没有再到A里面去找,一直找到Appdelegate,如果appdelegate也没有就会将当前事件作废。

应用

- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;    // recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system
这个方法主要可以用来设计项目结构,解藕。

- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;    // default returns YES if point is in bounds
这个主要用于一些不规则的按钮的实现
例:
创建一个类继承UIButton,并重写
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
     const CGFloat halfWidth = 100;
     CGFloat xOffset = point.x - 100;
     CGFloat yOffset = point.y - 100;
     CGFloat radius = sqrt(xOffset * xOffset + yOffset * yOffset);
     return  radius <= halfWidth;
}
这样就创建了一个圆形的按钮,响应事件也是在圆形内。
还有一些其他的应用就需要发挥想象了


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值