响应者链

参考文章

iOS开发 - 事件传递响应链
iOS以实例讲解响应者链

什么是响应者链

当我们在使用微信等工具,点击扫一扫,就能打开二维码扫描视图。在我们点击屏幕的时候,iphone OS获取到了用户进行了“单击”这一行为,操作系统把包含这些点击事件的信息包装成UITouch和UIEvent形式的实例,然后找到当前运行的程序,逐级寻找能够响应这个事件的对象,直到没有响应者响应。这一寻找的过程,被称作事件的响应链。
事件响应链

响应者

UIResponder

在iOS中,能够响应事件的对象都是UIResponder的子类对象。UIResponder提供了四个用户点击的回调方法,分别对应用户点击开始、移动、点击结束以及取消点击,其中只有在程序强制退出或者来电时,取消点击事件才会调用。

用户点击的回调方法

在iOS中,能够响应事件的对象都是UIResponder的子类对象。UIResponder提供了四个用户点击的回调方法,分别对应用户点击开始、移动、点击结束以及取消点击,其中只有在程序强制退出或者来电时,取消点击事件才会调用。

方法调用时机:

当点击并且鼠标有移动时,会依次调用began、moved、ended方法
在这里插入图片描述
而只有在程序强制退出或者来电时,取消点击事件才会调用。

响应事件

用到了UIView的两个方法

//搜索是在哪个视图
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
//判断是否在这个视图范围内
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event


事件的响应过程

1. 事件产生

当我们在使用微信等工具,点击扫一扫,就能打开二维码扫描视图。在我们点击屏幕的时候,iphone OS获取到了用户进行了“单击”这一行为,操作系统把包含这些点击事件的信息包装成UITouch和UIEvent形式的实例。

2. 寻找响应者

Application从事件队列中取出该事件,寻找响应这个事件的最佳视图。

寻找过程

//搜索是在哪个视图
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
//判断是否在这个视图范围内
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event


在hitTest中有一个循环查找视图,从上往下找(从UIWindow开始找)。

总结:

  1. 找到最合适的响应视图后事件会从此视图开始沿着响应链nextResponder传递,直到找到处理事件的视图,如果没有处理的事件会被丢弃。
  2. nextResponder规则为:如果有父视图则nextResponder指向父视图;如果是根视图则指向控制器;最后指向AppDelegate。

3. 已找到Responder,事件响应

有四个方法

// 一根或者多根手指开始触摸view,系统会自动调用view的下面方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
// 一根或者多根手指在view上移动,系统会自动调用view的下面方法(随着手指的移动,会持续调用该方法)
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
// 一根或者多根手指离开view,系统会自动调用view的下面方法
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
// 触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程,系统会自动调用view的下面方法
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;



如果找到的响应者responder不能响应事件,就会逐层往上找,形成响应者链。

我们根据上文的hitTest响应顺序和nextResponder顺序可以大概推测出有一个响应者栈:将可以响应(即pointInside: withEvent:为YES)的视图入栈,最后需要执行事件时再从栈中取视图,最上面的视图最先处理,如果无法处理则给下一个视图,直到AppDelegate如果都无法处理,则事件被摒弃。

  • 如果没有响应者
    一步步touchesBegan,再按touchesBegan的顺序,toucherEnded。
  • 如果有响应者
    一步步touchesBegan,然后去执行响应事件。

无法响应的情况

  1. alpha = 0;
  2. 字视图超出父视图;
  3. userInteractionEnabled = NO;
  4. hidden = Yes;

runloop & 触摸事件

在这里插入图片描述

  • IOKit
    框架获得用户空间访问硬件设备和驱动程序。

  • SpringBoard
    其实是一个标准的应用程序,这个应用程序用来管理IOS的主屏幕,除此之外像启动WindowSever(窗口服务器),bootstrapping(引导应用程序),以及在启动时候系统的一些初始化设置都是由这个特定的应用程序负责的。它是我们IOS程序中,事件的第一个接受者。它只能接受少数的事件比如:按键(锁屏/静音等),触摸,加速,接近传感器等几种Event,随后使用macport转发给需要的App进程。

  • SDK(感觉就是第三方库)
    SDK的英文全名是:software development kit,翻译bai成中文的意思就是“软件开发工具包”
    通俗一点的理解,是指由第三方服务商提供的实现软件产品某项功能的工具包。一般以集合kpi和文档、范例、工具的形式出现
    通常SDK是由专业性质的公司提供专业服务的集合,比如提供安卓开发工具、或者基于硬件开发的服务等。也有针对某项软件功能的SDK,如推送技术、图像识别技术、移动支付技术等,同时资源优势类的公司也提供资源共享的SDK,如一些广告SDK提供盈利渠道,分发SDK提供产品下载渠道。

    • SDK与API
      有一杯密封饮料,它的名字叫做“SDK”。
      饮料上插着吸管,吸管的名字叫“API”
      .
      把你叫做“XX系统”。
      如果你想喝到SDK里的饮料(让系统拥有SDK中的功能),你必须通过API这根吸管来实现(通过API连接你的系统和SDK工具包),否则你就喝不到饮料。所以:SDK=放着你想要的软件功能的软件包API=SDK上唯一的接口
      例子来源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值