iOS笔记-事件传递和响应

事件分三个类型,这里只说触摸事件

  • 触摸事件
  • 加速计事件
  • 远程控制事件

iOS中只有继承于UIResponder的对象才能处理事件,也就是响应者对象,而UIApplication,UIViewController,UIView都是继承于UIResponder

UIResponder提供了四个对象方法来处理事件:

// UIView是UIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件
// 一根或者多根手指开始触摸view,系统会自动调用view的下面方法
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
// 一根或者多根手指在view上移动,系统会自动调用view的下面方法(随着手指的移动,会持续调用该方法)
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
// 一根或者多根手指离开view,系统会自动调用view的下面方法
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
// 触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程,系统会自动调用view的下面方法
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

事件的产生和传递

事件的产生
  1. 发生触摸事件后,系统会将该事件加入到一个UIApplication管理的事件队列中
  2. UIApplication会从事件队列中取出最前面的事件,分发下去处理,通常会先把事件发送给应用程序的主窗口(keyWindow)
  3. 主窗口会在视图层次结构中找到一个最适合的视图处理触摸事件
事件的传递
  1. 首先判断主窗口是否召集处理事件
  2. 判断触摸点是否在自身
  3. 子控件数组中从后往前遍历子控件,然后重复123,直到视图没有子控件符合判断
  4. 没有符合条件的子控件就是事件响应者
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;
/* 
    寻找事件最适合的view
    (不管控件事件能处理事件,是否在触摸点范围内,事件都会传递给这个视图,然后调用hittest方法)
    可以通过重写hittest方法来修改响应事件的视图,拦截响应事件
    (真实响应者和要修改的响应者都要修改hittest,或者在两者父视图中相应位置返回要修改的响应者,避免真实响应者先执行了hittest方法)
*/
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event; 
/*
    判断事件触摸点是否在视图内,执行hittest方法中会执行此方法
    拦截此方法可以用来修改视图点击的响应范围
*/
顺序

事件的传递,从上到下,

UIApplication-UIWindow-UIView-initialView

事件的响应,从下到上

initialView-UIView-UIWindow-UIApplication

\color{red}{注意:}系统默认在视图没有实现响应方法的情况下会在touchesBegan中执行[super touchesBegan:touches withEvent:event]方法,将事件往上传递

  - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;

\color{red}{使用:}如果要做到一个事件多个视图进行响应,可以修改touchesBegan方法,执行完自定义操作之后,再调用系统的默认做法,再把事件交给上一个响应者处理[super touchesBegan:touches withEvent:event];

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容