iOS_响应者链 Responder Chain

文章目录

    • 简述
    • Hit-Test 机制 (找到最佳响应者)
    • 响应者链 Responder chain
    • 应用
      • 获取当前View的控制器对象:
      • 手势穿透:

简述

  • 传递链:
    系统向离用户最近的view传递。
    UIKit –> active app’s event queue –> window –> root view –> … –> lowest view

  • 响应链:
    由离用户最近的view向系统传递。
    initial view –> super view –> … –> view controller –> window –> Application –> AppDelegate

iOS中,只有继成UIResponder的对象才能接收并处理事件,UIReaponder是所有响应对象的基类,在UIResponder类中定义了处理上述各种事件的接口。UIApplication、UIViewController、UIWindow和所有继承直UIView和UIKit类都直接或间接的继承UIResponder,所以它们的实例都是可以构成响应者链的响应者对象。


在这里插入图片描述

Hit-Test 机制 (找到最佳响应者)

用户触摸,Touch -> UIEvent -> eventQueue -> UIApp -> UIWindow -> hitTest:withEvent: 查找触摸点所在视图。

当用户触摸屏幕时,系统首先要找到响应者Responder。将Touch以UIEvent的方式加入到UIApplication的事件队列中。UIApplication从事件队列中取出最新的事件传递到UIWindow。UIWindow通过 hitTest:withEvent: 方法寻找触摸点所在的视图,这个过程称之为hit-test view。

UIApplication -> UIWindow -> RootView -> supView -> View

在顶级视图(Root View)上调用pointInside:withEvent:方法判断触摸点是否在当前视图内;

如果返回NO,那么hitTest:withEvent:返回nil;

如果返回YES,那么它会向当前视图的所有子视图发送hitTest:withEvent:消息,所有子视图的遍历顺序是从最顶层视图一直到到最底层视图,即从subviews数组的末尾向前遍历,直到有子视图返回非空对象或者全部子视图遍历完毕。

响应者链 Responder chain

当系统通过Hit-Test机制找到触摸到的View,但是view没有或无法正确处理此次Touch。此时,系统便会通过响应者链寻找下一个响应者,对此次Touch进行相应:

View -> View Controller(如果存在)-> superView -> RootView -> UIWindow -> UIApplication


hitTest 实现原理大致如下:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {// 1、控件不允许与用户交互if (self.userInteractionEnabled == NO ||self.alpha <= 0.01 ||self.hidden == YES) {return nil;}// 2、点击的point不在当前控件内if (![self pointInside:point withEvent:event]) {return nil;}// 3、倒序遍历每一个子控件for (int i = (int)self.subviews.count - 1; i >= 0; i--) {UIView *childView = self.subviews[i];// 当前触控Point的坐标转换为相对于子控件的坐标CGPoint childPoint = [self convertPoint:point toView:childView];// 在子控件中找能响应的子控件(递归循环),从上层找起UIView *fitView = [childView hitTest:childPoint withEvent:event];if (fitView) {return fitView;}}// 4、子视图中没有能响应的view,就返回自己return self;
}// 该方法判断触摸点是否在控件上,point必须是方法调用者的坐标
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {return NO;
}

应用

获取当前View的控制器对象:

- (UIViewController *)getCurrentViewController{ UIResponder *next = [self nextResponder]; do { if ([next isKindOfClass:[UIViewController class]]) { return (UIViewController *)next; } next = [next nextResponder]; } while (next != nil); return nil; 
}

手势穿透:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {UIView *view = [super hitTest:point withEvent:event];if (self == view) {return nil;}return v;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/58206.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【设计模式系列】迭代器模式(七)

一、什么是迭代器模式 迭代器模式&#xff08;Iterator Pattern&#xff09;是一种行为型设计模式&#xff0c;它提供一种方法来顺序访问一个聚合对象中的各个元素&#xff0c;而不暴露其内部的表示。迭代器模式将集合的遍历过程封装在一个独立的迭代器对象中&#xff0c;这样…

纯GO语言开发RTSP流媒体服务器-RTSP推流直播、本地保存录像、录像回放、http-flv及hls协议分发

温馨提示&#xff1a;我们分享的文章是给需要的人&#xff0c;不需要的人请绕过&#xff0c;文明浏览&#xff0c;误恶语伤人&#xff01; 前言 在软件开发中遇到使用流媒体音视频的行业比较多&#xff0c;如安防监控系统、无人机巡逻视频上云处理、直播平台、教育与企业培训…

如何快速使用Cesium完成项目

要快速使用Cesium完成项目&#xff0c;可以按照以下步骤进行&#xff1a; 学习基础知识&#xff1a; 首先&#xff0c;了解Cesium的基本概念和功能。可以通过阅读Cesium的官方文档和一些入门教程来掌握基础知识。例如&#xff0c;可以参考“Cesium速成教程&#xff1a;一小时入…

代码随想录(十二)——图论

并查集 并查集主要有三个功能。 寻找根节点&#xff0c;函数&#xff1a;find(int u)&#xff0c;也就是判断这个节点的祖先节点是哪个将两个节点接入到同一个集合&#xff0c;函数&#xff1a;join(int u, int v)&#xff0c;将两个节点连在同一个根节点上判断两个节点是否在…

阿里云物联网的通信方式

阿里云物联网通信的两种方式&#xff0c;一个是物模型&#xff08;分为服务&#xff0c;事件&#xff0c;属性&#xff09;&#xff0c;一个是自定义topic&#xff08;要另外设置数据流转&#xff09; 1.使用产品内的功能定义&#xff0c;&#xff08;其实也就是Topic中定义好的…

ubuntu nginx 已经安装 letsencrypt 如何获取免费证书

如果你已经在 Ubuntu 上安装了 Nginx 和 Let’s Encrypt&#xff0c;以下是如何使用 Certbot 获取免费的 SSL 证书的步骤。 1. 安装 Certbot 和 Nginx 插件 即使你已经安装了 Let’s Encrypt&#xff0c;仍然需要安装 Certbot 和其 Nginx 插件来自动处理证书生成和配置。 更…

新手逆向实战三部曲之三——通过进入关键call追码注册软件(进阶)

教程开始&#xff1a; 通过前两次的学习&#xff0c;是不是感觉逆向也蛮有意思的呢&#xff0c;感兴趣的同学可以先看看前二次的内容再继续向下学习 新手逆向实战三部曲之一 新手逆向实战三部曲之二 有了上次爆破的基础&#xff0c;这次便省力了许多&#xff0c;这次从载入开始…

STM32第15章 RCC-使用HSE/HSI配置时钟

时间:2024.10.21-10.23 参考资料: 《零死角玩转STM32》“RCC-使用HSE/HIS配置时钟”章节 TIPS: 从前面的历程中我们知道,程序在启动的时候会执行汇编文件,汇编文件里会调用System_Init(固件库编程的函数),它里面会把时钟初始化成72M,因此前面我们在用固件库写程序的…

数据结构:“小猫钓鱼游戏”

一&#xff1a;题目 栈和队列的综合应用&#xff1a;“小猫钓鱼”的游戏规则是&#xff1a;将一副扑克牌平均分成两份&#xff0c;每人拿一份。玩家甲先拿出手中的第一张扑克牌放在桌上&#xff0c;然后玩家乙也拿出手中的第一张扑克牌&#xff0c;并放在玩家甲刚打出的扑克牌的…

采用Excel作为可视化设计器的开源规则引擎 NopRule

决策树和决策矩阵是业务人员可以直观理解的复杂IF-ELSE逻辑表达形式&#xff0c;也是规则引擎中最常用、最有用的部分。常见的规则引擎如Drools虽然提供了更加丰富的功能特性集&#xff0c; 特别是所谓的RETE算法可以用于高效复用多次重复出现的表达式片段&#xff0c;但在实际…

SpringSecurity + Jwt权限校验,接口调用403 Forbidden问题排查与解决

问题背景&#xff1a;部分接口调用正常&#xff0c;部分接口调用报403Forbidden&#xff0c;postman不显示具体报错信息。 问题描述&#xff1a; 接口调用报错&#xff0c;经排查&#xff0c;权限校验认证通过&#xff0c;可以进入接口&#xff0c;但是在执行过程中&#xff0…

【MySQL】提高篇—视图与存储过程:存储过程(Procedure)的创建与调用

在关系数据库中&#xff0c;存储过程&#xff08;Stored Procedure&#xff09;是一组预编译的 SQL 语句和可选的控制流语句&#xff08;如条件语句和循环语句&#xff09;&#xff0c;它们被存储在数据库中并可以被客户端应用程序或数据库用户调用。存储过程可以接受输入参数&…

深入了解 Android 中的命名空间:`xmlns:tools` 和其他常见命名空间

在 Android 开发中&#xff0c;xmlns &#xff08;.xml的namespace&#xff09;命名空间是一个非常重要的概念。通过引入不同的命名空间&#xff0c;可以使用不同的属性来设计布局、设置工具属性或者支持自定义视图等。除了 xmlns:tools 以外&#xff0c;还有很多常见的命名空间…

Java 线程池:深入理解与高效应用

在 Java 并发编程中&#xff0c;线程池是一种非常重要的技术。它可以有效地管理和复用线程&#xff0c;提高系统的性能和资源利用率。本文将深入探讨 Java 线程池的概念、原理、使用方法以及最佳实践&#xff0c;帮助读者更好地理解和应用线程池。 一、引言 在现代软件开发中&a…

高级SQL技巧掌握

高级SQL技巧掌握 在数据驱动的时代,掌握SQL不仅仅是为了解决具体问题,它更像是一把钥匙,帮助你打开数据分析的大门。你准备好提升你的SQL技能了吗?在这篇文章中,我们将一起探索十个必备的高级SQL查询技巧,这些技巧将帮助你更有效率地进行数据处理与分析。 1. 常见表表达…

从0到1学习node.js(npm)

文章目录 一、NPM的生产环境与开发环境二、全局安装三、npm安装指定版本的包四、删除包 五、用npm发布一个包六、修改和删除npm包1、修改2、删除 一、NPM的生产环境与开发环境 类型命令补充生产依赖npm i -S uniq-S 等效于 --save -S是默认选项npm i -save uniq包的信息保存在…

webpack 老项目升级记录:从 node-sass 限制的的 node v8 提升至支持 ^node v22

老项目简介 技术框架 vue 2.5.17webpack 4.16.5"webpack-cli": "3.1.0""node-sass": "^4.7.2" 几个阶段 第一步&#xff1a;vue2 升级到最新 第一步&#xff1a;升级 vue2 至最新版本&#xff0c;截止到目前&#xff08;2024-10-…

解决RabbitMQ脑裂问题

文章目录 前言一、现象二、解决办法 前言 RabbitMQ脑裂 一、现象 RabbitMQ镜像群出现脑裂现象&#xff0c;各个节点的MQ实例都“各自为政”&#xff0c;数据并不同步。 二、解决办法 # 停止mq sh rabbitmq-server stop_app # 查看mq进程是否存在 ps -ef | grep rabbitmq # …

ATom:加州理工学院化学电离质谱仪(CIT-CIMS)的现场数据,V2版

目录 简介 摘要 代码 引用 网址推荐 知识星球 机器学习 ATom: In Situ Data from Caltech Chemical Ionization Mass Spectrometer (CIT-CIMS), V2 ATom&#xff1a;加州理工学院化学电离质谱仪&#xff08;CIT-CIMS&#xff09;的现场数据&#xff0c;V2版 简介 该数…

trueNas 24.10 docker配置文件daemon.json无法修改(重启被覆盖)解决方案

前言 最近听说truenas的24.10版本开放docker容器解决方案放弃了原来难用的k3s&#xff0c;感觉非常巴适&#xff0c;就研究了一下&#xff0c;首先遇到无法迁移老系统应用问题比较好解决&#xff0c;使用sudo登录ssh临时修改daemon.json重启docker后进行docker start 容器即可…