iOS深入理解事件传递及响应

一、事件传递

事件传递相关的两个方法

objectivec 复制代码
// 哪个视图响应事件返回哪个  
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;     
// 点击位置是否在当前视图范围  
-(BOOL)pointInside(CGPoint)point withEvent:(UIEvent *)event; 

如图,View A中包含View B1、View B2,View B2中包含View C1,View C2既包含View C1的一部分,又包含View B2的一部分,View C1中包含View D。当点击View C2的空白区域时,系统如何找到事件响应者为View C2?

(1)事件传递流程

当用户点击屏幕的某个位置,该事件会被传递给UIApplicationUIApplication又传递给当前的UIWindow,UIWindow会通过hitTest:WithEvent:方法返回响应的视图。hitTest:WithEvent:方法内部通过pointInside:withEvent:方法判断点击point是否在当前UIWindow范围内,如果在,则会遍历其中的所有子视图SubViews来查找最终响应此事件的视图,遍历方式为倒序遍历,即最后添加到UIWindow的视图最优先被遍历到,依次遍历,可以看作是递归调用。每个UIView中又都会调用其对应hitTest:WithEvent:方法,最终返回响应视图hit,如果hit有值,则hit视图就作为该事件的响应视图被返回,如果hit没有值,但在当前UIWindow范围内,则当前UIWindow作为事件的响应视图。

(2)hitTest:WithEvent:系统内部实现

首先在hitTest:WithEvent:方法内部先判断当前视图的hidden属性、是否可交互、透明度是否大于0.01。如果该视图不同时满足上述3个条件,则返回nil,当前视图不作为事件的响应视图,当前视图的父视图继续遍历其他的子视图;如果该视图没有隐藏、用户可交互、透明度大于0.01,则会通过pointInside:WithEvent:方法判断点击的点是否在当前视图范围内,如果不在,则同样返回nil,当前视图仍不作为事件的响应者;如果在,则会通过倒序遍历当前视图的子视图,调用其子视图对应的hitTest:WithEvent:方法,如果某个视图返回了事件响应视图,则该返回的视图被作为事件的响应者,反之则继续遍历判断。如果遍历完后没有任何视图响应此事件,因为此事件点击的范围在当前视图范围内,则将当前视图作为事件响应者返回。

二、视图事件响应

上述讲述了视图事件的传递流程,当视图事件传递后,最终事件由谁来响应呢,这就涉及视图的响应链、响应链的机制和流程。 如图,页面存在一个UILabel一个UITextField、一个UIButton,实线箭头表示下一个响应者。

视图事件响应链相关的方法

objectivec 复制代码
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

例如,当点击View C2的空白处时,事件由谁来响应呢?首先由View C2接收事件,如果它不处理,就会把事件传递给View B2,如果View B2还不响应这个事件,View B2会通过响应链将事件传递给它的父视图View A,如果还不响应,则会沿着响应链一直向上传递,直到传递到UIApplicationDelegate仍然不对事件进行处理,则会忽略此事件

相关推荐
whuhewei1 小时前
为什么客户端不存在跨域问题
前端·安全
妮妮喔妮1 小时前
supabase的webhook报错
开发语言·前端·javascript
yivifu2 小时前
手搓HTML双行夹批效果
前端·html·html双行夹注
奔跑的卡卡3 小时前
Web开发与AI融合-第一篇:Web开发与AI融合的时代序幕
前端·人工智能
IT_陈寒3 小时前
Redis批量删除的大坑,差点让我加班到天亮
前端·人工智能·后端
帆张芳显3 小时前
智表ZCELL产品V3.6 版发布,新增系统预置右键菜单操作、页签栏操作等功能
前端·canva可画·excel插件
漂流瓶jz3 小时前
运行时vs编译时:CSS in JS四种主流方案介绍和对比
前端·javascript·css
Asmewill3 小时前
uv包管理命令
前端
发现一只大呆瓜3 小时前
深入浅出 Tree Shaking:Rollup 是如何“摇”掉死代码的?
前端·性能优化·vite
weixin199701080163 小时前
《转转商品详情页前端性能优化实战》
前端·性能优化