首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >事件传递、响应者链条

事件传递、响应者链条

作者头像
Helloted
发布于 2022-06-06 10:53:58
发布于 2022-06-06 10:53:58
1K00
代码可运行
举报
文章被收录于专栏:HellotedHelloted
运行总次数:0
代码可运行

一、事件

iOS里有三种事件:触摸(touch)、加速(motion)、远程控制

在UIResponder里,有以下事件处理

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 // 触摸事件
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
// 加速计事件
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;
// 远程控制事件
- (void)remoteControlReceivedWithEvent:(UIEvent *)event;

二、寻找响应者(UIResponder)-事件传递

响应者:继承UIResponder的对象称之为响应者对象,能够处理touchesBegan等触摸事件

当一个Touch事件产生时,要先找到响应者,iOS通过Hit-Test机制来寻找响应者,每一个UIView(继承自UIResponder)都有以下的方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event; 

HitTest的顺序

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
UIApplication -> UIWindow -> Root View -> subview -> ··· -> initalView
  1. 系统检测到手指触摸(Touch)操作时,将Touch 以UIEvent的方式加入UIApplication事件队列中。
  2. UIApplication从事件队列中取出最新的触摸事件进行分发传递到UIWindow进行处理。
  3. UIApplication和UIWindow通过sendEvent:方法传递事件
  4. UIWindow 之后会通过hitTest:withEvent:方法寻找触碰点所在的视图

hitTest:withEvent:原理

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 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.从后往前遍历自己的子控件,看是否有子控件更适合响应此事件
    int count = self.subviews.count;
    for (int 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;
}

三、响应者链条

当找到最合适的响应者之后, 便会调用控件相应的touches方法来作具体处理. 并将该事件随着响应者链条往回传递, 交给上一个响应者来处理. (即调用super的touches方法),从之前往下走的路线往上回传,在其中加入了Viewtroller来处理

  1. 如果view的控制器存在,就传递给控制器;如果控制器不存在,则将其传递给它的父View
  2. 在视图层次结构的最顶级视图,传递给ViewController
  3. ViewController将事件传递给window对象进行处理
  4. window对象继续将事件或消息传递给UIApplication对象
  5. 如果UIApplication也不能处理该事件或消息,响应者链条从头到尾,都未处理,则将其丢弃

事件不处理,指的是touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;方法不写。

四、实例分析

UIButton的继承链是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
UIButton->UIControl->UIView->UIResponder->NSObject

UIApplication能够接受事件,因为UIApplication和UIView一样继承自UIResponder

下面是一个点击事件的方法过程

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    UIButton *button = [UIButton buttonWithType:UIButtonTypeContactAdd];
    button.frame = CGRectMake(100, 100, 40, 40);
    [button addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
【算法竞赛】愚蠢的错点
邻接表,h[]忘记初始化。多组数据时,idx未初始化(会造成数组越界) 当使用并查集时,注意自己写的并查集是不是fa[x]随时都是x的祖宗,若不是,记得要用getfa(x) 变量名有冲突y1, next, prev, has ... 在特别情况下.size()和int整型变量比较时会出错,所以尽量保证式子的运算结果是正数,因为如果是负数,unsigned int类型的变量会变成超大的正数。 priority_queue 默认是大根堆 < Type,vector,greater >是小根堆 在自己写的函数里引
Livinfly
2022/10/26
2970
算法基础学习笔记——⑫最小生成树\二分图\质数\约数
罗列出每个数,依次删除每个数的倍数,剩下的数就是质数,可以对此进行优化,可以不删每一个数的倍数, 可以只删质数的倍数,这样就不用重复删。
命运之光
2024/03/20
1220
算法基础学习笔记——⑫最小生成树\二分图\质数\约数
【算法竞赛 - 搜索】Eight II
只是缺少了始末状态一致的数据,导致我血压高了几小时。(和标程对拍没有问题,交上去就WA)
Livinfly
2022/10/26
2280
【算法竞赛】AtCoder Beginner Contest 284 D, F
赛时并没有意识到枚举范围在三次根号n里,加上自己手写的二分sqrt挂了(丢人),一直没过去,后面把sqrt部分改好也就过了。
Livinfly
2023/01/08
3300
高级数据结构:带边权并查集&拓展域
作为家喻户晓的并查集,运用简单的几行代码就实现了多个数据间从属关系的高效维护和查找。最基本的并查集没啥好说的了,定义一个fa数组表示x的父亲,初始化所有数据一开始的父亲是自己,然后就是查找和合并的操作,自认为最简单的模板见下:
Here_SDUT
2022/08/08
1.2K0
高级数据结构:带边权并查集&拓展域
补题A-E Codeforces Round 953 (Div. 2)
假设每个点都投资1元,对于a[i],投资1元的期望收益是a[i]/n,总的期望收益是sum(a)/n。
WuShF
2025/02/26
991
补题A-E Codeforces Round 953 (Div. 2)
2018年第九届蓝桥杯B组题解
按着题目把这些数转换成8字节的二进制数就可以了,负数的二进制是补码。可以自己写个函数实现一下,实际效果图:
Ch_Zaqdt
2019/01/10
3K0
【算法竞赛】Namomo Winter 2023 Day 3 Div 2
Dashboard - 2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest - Codeforces
Livinfly
2023/01/11
3660
树状数组-从入门到拓展(转载非原创)
转载来源:https://www.cnblogs.com/AKing-/p/15311440.html
xlj
2021/09/20
4650
LeetCode周赛290,什么?你不会树状数组,这太不公平了
我们老规矩来看LeetCode周赛第290场。这一场比赛的赞助商是华为,应该说是目前为止赞助商当中规模最大的公司了。
TechFlow-承志
2022/09/21
5120
LeetCode周赛290,什么?你不会树状数组,这太不公平了
LeetCode第333场,第二题差点没做出来是几个意思……
这次的赛题难度稍大,多花了点时间……照惯例咱们来聊一聊上周的LeetCode周赛,这一次是第333场。由佳期投资赞助,并且前100名的同学可以获得简历直通的机会。这已经好久没有出现了,算是市场行情的一个参照物吧。
TechFlow-承志
2023/03/02
5330
LeetCode第333场,第二题差点没做出来是几个意思……
【算法竞赛】水CF构造题
我太弱了,水水构造tag的题去。 大概只写写思路(毕竟构造题) 打*的是自己想没直接出来的。 发布时间,最早为20220814-14:14,现在为最新水题时间。
Livinfly
2022/10/26
4900
《算法竞赛进阶指南》0x14 Hash
与离散化思想类似,当我们要对若干复杂信息进行统计时,可以用 Hash函数 把这些复杂信息映射到一个容易维护的值域内
一只野生彩色铅笔
2022/10/31
1.8K0
LCS、LIS、LICS算法
给定两个序列 ,设 为 的长度,其中 分别表示 从首元素到第 i 个元素的一段、 从首元素到第 个元素的一段, 分别表示 中第 i个元素、 中第 个元素,序列 和 的长度分别为 和 。则 的状态转移方程为:
hotarugali
2022/03/01
8840
程序员进阶之算法练习(六十五)
题目链接 题目大意: 给出n个整数和整数x,问能否找到一个顺序: 按照这个顺序累加数字,中间不会出现数字和等于x; 已知n个整数互不相同。
落影
2022/09/23
1710
算法竞赛偷分技巧
读取第k位:a>>k&1读取第k位并取反:心a>>k&1将第k位清0:a&=(1<< k)将第k位置1:a|=1<< k将第k位取反:a^=1<< k将第k1~k2位反转:a^=((1<< (k2-k1+1))-1)<< k2是否恰好只有一个true:!(x&(x-1))&&x判断是否有两个相邻的true:X>>1&X是否有三个相邻的txue:X>>1&X>>2&X
用户11062199
2024/06/19
1370
《算法竞赛进阶指南》0x18 总结与练习
这一天,刚刚起床的达达画了一排括号序列,其中包含小括号 ( )、中括号 [ ] 和大括号 { },总长度为
一只野生彩色铅笔
2022/10/31
9940
《算法竞赛进阶指南》0x18 总结与练习
《算法竞赛进阶指南》0x24 迭代加深
这种策略带有一定的缺陷:如果搜索树每个节点的分支数目非常多,且问题的答案在某个较浅的结点上,如果深搜在一开始选错了分支,就可能在不包含答案的深层次树上浪费许多时间
一只野生彩色铅笔
2022/10/31
8440
Codeforces 的题目真的值得算法竞赛选手训练吗?
个串,有两种操作,一种是给某个串加一个字符,另一种是求存不存在一个串是查询串的子串。强制在线。
ACM算法日常
2021/11/10
9780
wz刷题汇总
个人刷题记录(不完全) cf-contests 存一些让我再写不一定写得来的或者我可能去扒原题的? 1202D d3线下想的数学题 1214D dfs可以搞 两次dfs 第一次把走过的路堵上(“D不是
wenzhuan
2022/08/15
4000
相关推荐
【算法竞赛】愚蠢的错点
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档