当前位置: 首页 > article >正文

iOS 中,用户点击一个按钮到响应的全部流程

在 iOS 中,当用户点击一个按钮(或其他 UI 控件)时,会触发一系列复杂的操作流程,从硬件到软件,再到应用层的事件处理。以下是从用户点击一个按钮到应用响应的完整流程:

  1. 硬件层:触摸事件的生成

    • 用户用手指点击屏幕。
    • 屏幕(电容式触摸屏)检测到用户的触摸事件。触摸屏幕的电容变化会被屏幕的传感器检测到。
    • 触摸控制器(Touch Controller)将这些电容变化转化为电信号。

  2. 硬件驱动层:事件传递到操作系统内核

    • 电信号通过硬件总线传递到设备的触摸屏控制器(Touch Screen Controller)。
    • 触摸屏控制器通过中断通知设备的主处理器(CPU),告知其触摸事件的发生。
    • iOS 内核中的触摸驱动程序(Touch Driver)接收触摸事件,并将其转化为可理解的坐标数据(如屏幕上的位置)。

  3. iOS 内核和系统框架层:事件生成和传递

    • 内核将触摸事件封装成IOHIDEvent(I/O Human Interface Device Event)事件对象。
    • IOHIDEvent 事件传递给 iOS 的用户层,通常通过 IOKit 和 CoreGraphics 等框架进行处理。
    • iOS 系统中的 UIApplication 类接收并处理低级别的触摸事件,然后将它们转化为更高层的 UIKit 事件(如 UIEvent)。

  4. UIKit 框架层:事件分发

    • UIApplication 对象作为应用的主事件循环的入口,它接收到事件后会分发给合适的窗口对象(UIWindow)。
    • UIWindow 对象根据事件的位置,找到事件目标视图(UIView)并将事件传递给它。
    • 视图(UIView)层次结构中的每一个视图都可以通过 hitTest(:with:) 方法确定触摸事件的最接近的目标视图。
    • 触摸事件从根视图(通常是应用的主窗口)开始,沿着视图层次结构向下传递。
    • 每个视图的 hitTest(
    :with:) 方法会调用 point(inside:with:) 方法,判断事件的坐标是否在该视图的区域内。
    • 最终,事件传递给包含该坐标的最深层次的视图,即最前面的视图。

  5. UIView 层:事件处理

    • 找到目标视图后,该视图会接收触摸事件,并调用相应的事件处理方法。
    • 对于触摸事件,目标视图会调用 touchesBegan(:with:)、touchesMoved(:with:)、touchesEnded(:with:) 或 touchesCancelled(:with:) 方法。
    • 这些方法由目标视图的类实现,可以被子类重写以自定义事件处理逻辑。
    • 如果视图是一个按钮(UIButton),并且已设置了目标和操作(Target-Action),UIKit 会自动调用相应的操作方法。
    • 按钮内部定义了事件处理方法,如 touchUpInside,当触摸在按钮内抬起时,会触发该方法。

  6. 目标-动作(Target-Action)机制:动作触发

    • 当按钮收到触摸事件时,会检查是否设置了 Target-Action 处理程序。
    • 如果设置了 Target-Action,UIKit 框架会调用目标对象的对应方法(通常是视图控制器中的一个方法)。

  7. 应用层:动作方法执行

    • 目标对象(通常是 UIViewController 或自定义的视图类)执行与 Target-Action 关联的动作方法。
    • 在这个动作方法中,可以定义任何应用程序逻辑,如导航到另一个视图控制器、更新 UI、发起网络请求等。

  8. 视图的更新与显示

    • 如果动作方法改变了应用的状态或需要更新 UI,会调用 UIKit 方法,如 setNeedsDisplay() 或 layoutIfNeeded()。
    • UIKit 将这些更新请求排队,并在下一个主线程循环周期重新渲染和更新 UI。

  9. 主运行循环:事件循环继续

    • 主运行循环继续运行,等待下一次事件触发,如用户的另一次触摸或定时器触发等。

总结

整个过程涉及多个层次,从硬件传感器检测到用户触摸,到操作系统内核处理事件,再到 UIKit 事件分发和应用层的响应。这个流程保证了 iOS 应用在用户与设备交互时能够实时响应,并提供流畅的用户体验。


http://www.kler.cn/a/294339.html

相关文章:

  • 深入探索:Scrapy深度爬取策略与实践
  • 「Mac玩转仓颉内测版12」PTA刷题篇3 - L1-003 个位数统计
  • 使用API有效率地管理Dynadot域名,编辑账户中whois联系人信息
  • apache2配置多站点
  • C语言 | Leetcode C语言题解之第557题反转字符串中的单词III
  • 【插件】多断言 插件pytest-assume
  • 【网络安全】服务基础第二阶段——第二节:Linux系统管理基础----Linux统计,高阶命令
  • 利用Spring Boot打造图书个性化推荐平台
  • C语言练习题之 数组中出现次数超过一半的数
  • C# 通过拖控件移动窗体
  • MySQL · 性能优化 · 提高查询效率的实用指南(上)
  • 第十四节:学习Springboot 的restful接口风格(自学Spring boot 3.x的第三天)
  • ROADM(可)-介绍
  • 【Linux网络编程】协议|OSI模型|TCP/IP模型|局域网通信|跨网络通信|地址管理|流程图
  • Kafka和ES加密
  • 深度学习dataset等概念
  • 【杂谈】-国产单片机学习成本高的原因分析
  • Deep Ocr
  • Flask如何处理静态文件
  • Spring拦截器与Servlet过滤器区别
  • Unity3D DOTS Component详解
  • 人机交互中的当斯定律
  • Redis数据持久化方法
  • 要在nginx中配置后端三个服务器的轮询和加权
  • Linux下安装和使用SVN及常用操作命令详解
  • 玩转Python Turtle库,实现满屏飘字的魔法!