iOS事件

作者: NapoleonY | 来源:发表于2018-06-14 16:29 被阅读16次

概述

iOS中事件有触摸事件、加速计事件、远程控制事件,下面以触摸事件为例研究下iOS事件相关的内容


iOS事件分类

UIResponsder

iOS中继承了UIResponsder的对象才能够响应事件,如UIViewControllerUIViewUIApplication
UIResponsder能够响应事件的原因是:提供了几个方法来处理事件

//触摸事件
- (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;

备注:

  1. 当多个手指同时触摸屏幕时,只会调用一次touchesBegan:withEvent:方法,touches中包含多个UITouch对象,分别对应着触摸屏幕的手指
  2. 如果是UIViewController的事件,在UIViewController中重写上面用到的方法即可;如果是UIView的事件,需要在子类中重写上面用到的方法

实例:触摸屏幕,移动屏幕上的某个UIButton

UIView的子类中重写touchesMoved: withEvent:方法

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:self];//当前点的位置
    CGPoint previousPoint = [touch previousLocationInView:self];//上一个点的位置
    CGFloat xPoint = point.x - previousPoint.x;
    CGFloat yPoint = point.y - previousPoint.y;
    NSLog(@"point:%@;previousPoint:%@;xPoint:%f;yPoint:%f",NSStringFromCGPoint(point), NSStringFromCGPoint(previousPoint), xPoint, yPoint);
    CGPoint centerPoint = self.btn.center;
    centerPoint = CGPointMake(centerPoint.x + xPoint, centerPoint.y + yPoint);
    self.btn.center = centerPoint;
}

iOS 事件处理过程

iOS事件分为事件传递、事件响应两个过程。

事件的产生

发生触摸事件后,系统会将事件加入到由UIApplication管理的队列(先进先出FIFO),然后将队列最前面的事件分发下去:UIApplication->keyWindow->视图层次结构,找到合适的视图控件后,就会调用对应控件的事件方法(touchesBegan: withEvent:等)来处理对应的事件。

事件的传递

触摸事件的传递是从父控件传递到子控件

  • 寻找响应事件的控件步骤
    1. 首先判断keyWindow是否能响应事件
    2. 触摸点是否在自己身上
    3. 从后往前遍历子控件,重复前面的两个步骤(首先查找数组中最后一个元素)
    4. 如果没有符合条件的子控件,那就认为自己可以处理
  • UIView不能响应事件的三种情况
  1. 不允许交互userInteractionEnabled = NO
  2. 隐藏的控件不能接收事件
  3. 透明度:如果设置一个控件的透明度<0.01,会直接影响子控件的透明度。

事件传递实例

注意:如果父控件不能接收触摸事件,那么子控件就不可能接收到触摸事件

事件传递实例

查找符合条件的控件原理

主要是通过以下两个控件实现查找

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;//返回nil,表明当前view以及子view没有能够响应事件的;如果不为nil,则表明当前view中有能响应事件的
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;//返回YES,表明触摸点在当前view中

通过调用hitTest:withEvent:可以判断是否有能够响应事件的控件,具体步骤为:
产生触摸事件->UIApplication事件队列->[UIWindow hitTest:withEvent:]->返回合适的view->[子控件 hitTest:withEvent:]->返回合适的view
不过子控件是否能够响应事件,父控件都会把事件传递给子控件,如果子控件不能响应事件,则父控件响应事件

实例:view中的button响应事件

参考iOS超出父视图后点击事件不响应,文中想要view中的button响应点击事件,因此重写了hitTest:withEvent:方法

响应者链

在iOS程序中无论是最后面的UIWindow还是最前面的某个按钮,它们的摆放是有前后关系的,一个控件可以放到另一个控件上面或下面,那么用户点击某个控件时是触发上面的控件还是下面的控件呢,这种先后关系构成一个链条就叫“响应者链”。

事件响应过程
  • 如果当前控件无法响应事件,就将事件按照视图层级结构(最上层是根视图)向上传递。如果当前view是控制器的view,那么控制器就是上一个响应者,事件就传递给控制器;如果当前view不是控制器的view,那么父视图就是当前view的上一个响应者,事件就传递给它的父视图
  • 在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理
  • 如果window对象也不处理,则其将事件或消息传递给UIApplication对象
  • 如果UIApplication也不能处理该事件或消息,则将其丢弃

总结

  1. 触摸屏幕产生触摸事件后,触摸事件会被添加到由UIApplication管理的事件队列中
  2. UIApplication会从事件队列中取出最前面的事件,把事件传递给keyWindow
  3. keyWindow会在视图层次结构中找到一个最合适的视图来处理触摸事件
  4. 最合适的view会调用自己的touches方法处理事件,如果不能处理事件,就将事件沿着响应者链向上抛

参考

  1. iOS事件传递->处理->响应
  2. iOS超出父视图后点击事件不响应

相关文章

  • iOS 事件以及手势的处理

    iOS 事件以及手势的处理 首先引用深入浅出iOS事件机制,iOS触摸事件处理详解,详解iOS触摸事件与手势识别三...

  • iOS 事件的传递响应机制

    iOS 中的事件 触摸事件 加速计事件 远程控制事件 iOS 中的触摸事件1、触摸事件发生,操作系统iOS会将此类...

  • iOS事件的响应者链

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

  • iOS 点击事件传递及响应

    1.iOS中的事件 iOS中的事件可以分为3大类型: 触摸事件加速计事件远程控制事件这里我们只讨论iOS中的触摸事...

  • iOS事件

    概述 iOS中事件有触摸事件、加速计事件、远程控制事件,下面以触摸事件为例研究下iOS事件相关的内容 UIResp...

  • iOS 响应链

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

  • 事件、事件响应链、手势分析

    一.事件 1.iOS三大事件包含触摸事件,设备移动事件,远程控制事件 2.iOS规定只有继承UIResponder...

  • 《iOS事件触摸与手势》

    iOS事件触摸与手势 一、事件分发处理【由外到内】在iOS中发生触摸后,事件会加到UIApplication事件队...

  • iOS事件处理机制

    事件类型 iOS的事件可以分为三类:触摸事件,加速计事件,远程控制事件 iOS中不是任何对象都能处理对象,只有继承...

  • iOS 触摸事件与响应理解

    参考文章: iOS触摸事件的流动 iOS触摸事件的传递与响应 UIViewController UIAppli...

网友评论

      本文标题:iOS事件

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