iOS-事件传递和响应机制

NSLog(@"SHOW TIME...");

App通过响应者对象来接收和处理事件,响应者对象都是UIResponder的子类对象,常见的UIView,UIVieController、UIWindow和UIApplication都是UIResponder的子类。

一、事件传递流程

- 当点击屏幕后,事件会传递给UIApplication,在由UIApplication传递给当前的UIWindow;

- UIWindow通过调用- (UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event方法返回响应视图。

- 其中hitTest:withEvent:内部会调用- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event方法判断点击位置是否在UIWindow范围内,

- 如果是的话就会【倒序遍历】(最后添加的视图最先遍历)UIWindow的子视图,从而找出响应视图并返回。

流程如下图1-1

                                                                                       图1-1 事件传递流程

二、hitTest:withEvent:内部都做了什么?

1、 首先会判断当前视图是否有响应事件的能力,当视图隐藏属性hidden=NO、交互userInteractionEnabled=YES、透明度alpha>0.01三者同时满足才拥有响应能力。
2、 若当前视图未拥有响应能力,hitTest方法直接返回nil,并且将当前视图的父视图作为时间响应者返回。
3、 若当前视图拥有响应事件能力,则继续判断事件点击位置是否在当前视图范围内,若不在则输出效果同步骤2,若在范围内,则倒序遍历当前视图的子视图,重复以上动作,直到找出响应视图。

具体流程如图1-2

                                                                 图1-2 hitTest:withEvent:内部实现流程

三、事件的响应链机制流程

当事件触发后,系统会自动为我们找到合适的响应对象,响应对象对事件逐级向上响应的过程就是响应链,和事件传递流程可以说是恰好相反,如下图1-3

                                                                                                    图1-3 事件响应链流程

- 我们根据下图1-4来走一遍响应机制。

                        图1-4 事件响应流程示例图

如图1-4,View A视图有View B2视图,View B2视图内有View C1和View C2两个子视图,此时点击空白圆的位置,系统会找到响应者C2视图,若C2视图不处理这个响应事件,会把事件传递给下一个响应者B2,若B2也不处理,在把事件传递给下一个响应者A视图,如果依旧不处理,则会沿着响应链向上传递直到传递给UIApplicationDelegate。如果一直没有视图响应事件的话,系统就会忽略这个事件(不会产生crash)。

四、Responder提供4个事件处理方法

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

- 其中touches是一个存放UITouch对象的集合,UITouch对象保存着手指触摸相关信息,如触摸位置、时间等。

- 一根手指触摸,会调用一次touchesBegan:方法,并且touches集合中包含1个UITouch对象;

- 两根手指同时触摸一个view,view只调用一次touchesBegan:方法,并且touches集合中包含2个UITouch对象;

- 两根手指一前一后触摸一个view,view调用两次touchesBegan:方法,并且每次touches都只包含1个UITouch对象;

 

NSLog(@"END...");

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值