美文网首页iOS技巧
iOS事件的响应者链

iOS事件的响应者链

作者: 徐文俊 | 来源:发表于2017-07-13 17:28 被阅读47次

iOS 事件响应者链

1 iOS中的事件

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

在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接受并处理事件,我们称之为“响应者对象”。以下都是继承自UIResponder的,所以都能接收并处理事件。

UIApplication

UIViewController

UIView

那么为什么继承自UIResponder的类就能够接收并处理事件呢?

UIResponder内部提供了以下方法来处理事件触摸事件

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

- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event;

- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event;

- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event;

加速计事件

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent*)event;

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent*)event;

- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent*)event;

远程控制事件

- (void)remoteControlReceivedWithEvent:(UIEvent*)event;

2 事件的处理

// UIView是UIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件

// 一根或者多根手指开始触摸view,系统会自动调用view的下面方法

- (void)touchesBegan:(NSSet *)toucheswithEvent:(UIEvent *)event

// 一根或者多根手指在view上移动,系统会自动调用view的下面方法(随着手指的移动,会持续调用该方法)

- (void)touchesMoved:(NSSet *)toucheswithEvent:(UIEvent *)event

// 一根或者多根手指离开view,系统会自动调用view的下面方法

- (void)touchesEnded:(NSSet *)toucheswithEvent:(UIEvent *)event

// 触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程,系统会自动调用view的下面方法

- (void)touchesCancelled:(NSSet *)toucheswithEvent:(UIEvent *)event

// 提示:touches中存放的都是UITouch对象


3 事件的产生和传递

3.1 事件的产生

3.1.1 发生触摸事件后,系统会将该事件加入到UIApplication管理的事件队列中(队列是先进先出,栈是先进后出)。

3.1.2 UIApplication从事件队列中取出最前面的事件,并将事件分发下去已便处理,通常,先发送事件给应用程序的主窗口(keyWindow)。

3.1.3 主窗口在视图层次结构中找到一个最合适的视图来处理触摸事件,这也是整个事件处理过程的第一步。

3.1.4 找到合适的视图控件后,就会调用视图控件的touches方法来做具体的事件处理。

3.2 事件的传递

3.2.1 触摸事件的传递是从父控件传递到子控件(UIApplication —> window -> 寻找处理事件最合适的View)。

3.2.2 首先判断主窗口(keyWindow)自己是否能接受触摸事件。

3.2.3 判断触摸点是否在自己身上。

3.2.3  子控件数组中从后往前遍历子控件,重复前面的两个步骤(从最上层的View开始)。

3.2.4  如果没有符合条件的子控件,那么就认为自己最合适处理这个事件,也就是自己是最合适的view。

3.3 寻找最适合的View的底层

//作用:寻找最适合的View

//什么时候调用:只要事件一传递给一个控件,这个控件就会调用他自己的hitTest:withEvent:方法

-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {

UIView *fitView = [super hitTest:point withEvent:event];

NSLog(@"%@",fitView); return fitView;

}

//作用:判断触摸点在不在当前的View上.

//什么时候调用:在hitTest方法当中会自动调用这个方法.

//注意:point必须得要跟当前View同一个坐标系.

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {

return YES;

}

hitTest: withEvent:的底层实现原理

// 判断自己能否接收事件

if(self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01){

return nil;

}

// 触摸点在不在自己身上

if ([self pointInside:point withEvent:event] == NO) {

return nil;

}

// 从后往前遍历自己的子控件(重复前面的两个步骤)

int count = (int)self.subviews.count; for (int i = count -1; i >= 0; i--) {

UIView *childV = self.subviews[i];

// point必须得要跟childV相同的坐标系.

// 把point转换childV坐标系上面的点

CGPoint childP = [self convertPoint:point toView:childV];

UIView *fitView = [childV hitTest:childP withEvent:event];

if (fitView) {

return fitView;

}

}

// 如果没有符合条件的子控件,那么就自己最适合处理

return self;

UIView不能接收触摸事件的三种情况1.不允许用户交互userInteractionEnabled = NO。2.当一个控件隐藏时Hidden = YES(如果把父控件隐藏,那么子控件也会隐藏,隐藏的控件不能接收触摸事件)。3.当一个控件为透明时。

相关文章

  • iOS 响应链

    iOS开发 - 事件传递响应链iOS 响应者链,事件的传递事件传递之响应链Cocoa Touch事件处理流程--响...

  • iOS UI事件传递与响应者链

    iOS UI事件传递与响应者链 响应者链 响应者对象:继承自UIResponder的对象称之为响应者对象。UIAp...

  • ios响应者链

    iOS 响应者链 字数418 阅读41 评论0 喜欢3 响应者链 响应者链是一个响应者的连接序列,事件或者动作消息...

  • 二、事件传递链和响应者链

    iOS触摸事件详解iOS开发-事件传递响应链 响应者链 UIResponser包括了各种Touch message...

  • iOS 响应者链

    一个目前最新最全的分析 iOS事件处理,看我就够了~ 对响应者链机制的图文分析 深入浅出iOS事件机制 对响应者链...

  • 转载:响应者链工作原理

    响应者链 响应者链是由一个一个响应者组成的长链;响应者链定义了iOS中触摸事件的交互规则;如果hit-test检测...

  • 事件的分发和传递

    响应者: 在iOS中,响应者为能响应事件的UIResponder子类对象,如UIButton、UIView等。 响...

  • iOS基础篇-事件处理

    1、首先需要理解iOS事件处理机制 理解事件处理、响应者、响应者链概念https://developer.appl...

  • iOS事件的响应者链

    iOS 事件响应者链 1 iOS中的事件 触摸事件 加速计事件 远程控制事件 在iOS中不是任何对象都能处理事件,...

  • iOS中对于响应链的理解

    对于响应链的理解: 在IOS中,有响应者链对事件进行响应,所有的响应类都是UIResponder的子类,响应者链是...

网友评论

    本文标题:iOS事件的响应者链

    本文链接:https://www.haomeiwen.com/subject/psovhxtx.html