✅作者简介:大家好我是瓜子三百克,励志成为全栈工程师的一枚程序猿,也是喜欢在学习和开发中记录笔记的小白博主!
📃个人主页:瓜子三百克的主页
🔥系列专栏:iOS
💖如果觉得博主的文章还不错的话,请点赞👍+收藏⭐️+留言📝支持一下博主哦🤞
当我们在手机上点击、滑动等屏幕操作进入到相应的页面,手机是如何区分相应指令并响应的呢?其中又是经历了怎样的过程呢?这里涉及到了事件响应链。
如下图所示,用户点击屏幕时,首先UIApplication
对象先收到该点击事件,再依次传递给它上面的所有子view,直到传递到最上层,即UIApplication ——> UIWindow ——> RootViewController ——> View ——> Button
,即传递链。
而反之Button ——> View ——> RootViewController ——> UIWindow ——> UIApplication
则称为响应链。
简单总结,事件链包含传递链和响应链,事件通过传递链传递上去,通过响应链找到相应的UIResponse
。
由系统向离用户最近的view传递,如上图所示。具体流程如下:
1、用户在点击屏幕。
2、系统将点击事件加入到UIApplication
管理的消息队列中。
3、UIApplication
会从消息队列中取出该事件传递给UIWindow
对象;
4、在UIWindow
中调用方法hitTest:withEvent:
返回最终相应的view
;
1、在
hitTest:withEvent:
方法中调用pointInside:withEvent:
来判断当前点击的点是否在UIWindow
内部;
2、如若返回yes,则倒序遍历其子视图找到最终响应的子view;
3、如果最终返回一个view,那么即为最终响应view并结束事件传递,如果无值返回则将UIWindow作为响应者。见下图:
其中核心方法如下:
// recursively calls -pointInside:withEvent:. point is in the receiver's coordinate system
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;
// default returns YES if point is in bounds
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;
方法hitTest:withEvent:
用来获取最终响应事件的view。
方法pointInside:withEvent:
,用来判断点击的位置是否在视图范围内。
以下为UIView不接受事件处理的情况:
view.hidden = YES;
view.userInteractionEnabled = NO;
view.alpha < 0.01;
由离用户最近的view向系统传递。如下所示:
响应链处理具体流程:
1、若view的
viewcontroller
存在,则将该事件传递给其viewcontroller
响应;如若不存在,则传递给其父视图;
2、若view的最顶层不能处理事件,则传递给UIWindow进行处理;
3、若UIWindow不能处理,则传递给UIApplication;
4、若UIApplication不能处理,则将该事件丢弃。
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *touchView = self;
// 1、判断 self 是否可以接受事件处理
// 2、判断 self 是否在点击区间
if (self.hidden == NO
&& self.alpha >= 0.01
&& [self pointInside:point withEvent:event]) {
// 3、便利所有子view
for (UIView *subView in self.subviews) {
// 4、获取点击的点在子view上的坐标
CGPoint subPoint = [subView convertPoint:point fromView:self];
// 5、递归获取点击响应的子view
UIView *subTouchView = [subView hitTest:subPoint withEvent:event];
if (subTouchView) {
touchView = subTouchView;
break;;
}
}
} else {
// 不接受事件处理直接返回 nil;
touchView = nil;
}
return touchView;
}
优秀讲解推荐: https://blog.csdn.net/songzhuo1991/article/details/122667980
🏆结束语🏆
如
果
觉
得
我
写
的
内
容
对
您
有
帮
助
的
话
:
\textcolor{green}{如果觉得我写的内容对您有帮助的话:}
如果觉得我写的内容对您有帮助的话:
欢
迎
点
赞
✌
,
收
藏
✌
,
加
关
注
✌
哦
,
谢
谢
!
!
\textcolor{green}{欢迎点赞✌,收藏✌,加关注✌哦,谢谢!!}
欢迎点赞✌,收藏✌,加关注✌哦,谢谢!!