iOS事件处理

作者: 木夜溯 | 来源:发表于2016-02-15 16:53 被阅读693次

    iOS中的事件以下三种
    1. 触摸事件
    2. 加速器事件:重力感应,旋转等事件
    3. 远程遥控事件:蓝牙线控,耳机线控等

    触摸事件

    响应者对象

    响应者对象是能够响应并处理事件的对象,是构成响应链和事件传递链的节点。
    常见的响应者对象有:UIApplication、UIViewController、UIView,都继承自UIResponder。其继承链如下:


    responder 继承链

    UIResponder的类相关定义如下:

    @interface UIResponder : NSObject
    
    - (nullable UIResponder*)nextResponder;
    
    - (BOOL)canBecomeFirstResponder;    // default is NO
    - (BOOL)becomeFirstResponder;
    
    - (BOOL)canResignFirstResponder;    // default is YES
    - (BOOL)resignFirstResponder;
    
    - (BOOL)isFirstResponder;
    
    /**** 触摸事件方法,对触摸事件进行处理 *****/
    - (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:(nullable NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
    - (void)touchesEstimatedPropertiesUpdated:(NSSet * _Nonnull)touches NS_AVAILABLE_IOS(9_1);
    
    /*** 加速器事件方法,对其进行处理  ***/
    - (void)motionBegan:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
    - (void)motionEnded:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
    - (void)motionCancelled:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(3_0);
    
    /***  遥控事件方法 ***/
    - (void)remoteControlReceivedWithEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(4_0);
    
    @end
    

    从UIResponder类中可以看到,需要处理触摸,加速器和遥控等事件时需要重写响应的方法,对UITouch和UIEvent进行处理。

    UITouch对象是一个手指接触到屏幕并在屏幕上移动或离开屏幕时创建的。它有几个属性和实例方法:

    phase:属性,返回一个阶段常量,指出触摸开始、继续、结束或被取消,是一个枚举配型,包含了
    ·UITouchPhaseBegan(触摸开始)
    ·UITouchPhaseMoved(接触点移动)
    ·UITouchPhaseStationary(接触点无移动)
    ·UITouchPhaseEnded(触摸结束)
    ·UITouchPhaseCancelled(触摸取消)
    tapCount:属性,轻按屏幕的次数
    timeStamp:属性,触摸发生的时间
    view:属性,触摸始于那个视图
    window:属性,触摸始于哪个窗口
    lacationInView:方法,触摸在指定视图中的当前位置
    previousLocationView:方法,触摸在指定视图中的前一个位置
    

    UIEvent对象包含一组相关的UITouch对象,由UITouch对象组成UIEvent对象,可以理解成一个完整的触摸操作是一个UIEvent,而这一系列完整操作中的每个点就是UITouch(按下、移动、离开)。
    UIEvent的作用是提供相关触摸操作的列表,如果要获取在屏幕上触摸的手势,可以使用该对象,这一些列操作都存储在Foundation框架中的NSSet对象中。

    响应链

    当触摸事件发生时,必须知道有谁来响应事件,所以会进行一个事件响应的一个传导,这就叫做响应链。

    每一个应用有一个响应者链,我们的视图结构是一个N叉树(一个视图可以有多个子视图,一个子视图同一时刻只有一个父视图),而每一个继承UIResponder的对象都可以在这个N叉树中扮演一个节点。当叶节点成为最高响应者的时候,从这个叶节点开始往其父节点开始追朔出一条链,那么对于这一个叶节点来讲,这一条链就是当前的响应者链。响应者链将系统捕获到的UIEvent与UITouch从叶节点开始层层向下分发,期间可以选择停止分发,也可以选择继续向下分发。

    事件响应链

    从图中可以看到,响应者链有以下特点:

    1. 响应者链通常是由 initial view 开始;
    1. UIView的nextResponder它的superview;如果UIView已经是其所在的 UIViewController的top view, 那么UIView的nextResponder 就是UIViewController;
    2. UIViewController 如果有 Super ViewController,那么它的 nextResponder 为其 Super ViewController 最表层的 View;如果没有,那么它的 nextResponder 就是 UIWindow;
    3. UIWindow 的 contentView 指向 UIApplication,将其作为 nextResponder;
    4. UIApplication 是一个响应者链的终点,它的 nextResponder 指向nil,整个 responder chain 结束。

    所有事件响应的类都是UIResponder的子类,响应者链是一个由不同对象组成的层次结构,其中的每个对象将依次获得响应事件消息的机会。当发生事件时,事件首先被发送给第一响应者,第一响应者往往是事件发生的视图,也就是用户触摸屏幕的地方。事件将沿着响应者链一直向下传递,直到被接受并做出处理。

    一个典型的响应链路线图如下:

    initial view –> super view –> …..–> view controller –> window –> Application –> AppDelegate
    

    hitTest

    当用户与 iPhone 的触摸屏产生互动时,硬件就会探测到物理接触并且通知操作系统。操作系统就会创建相应的事件,并将其传递给当前正在运行的应用程序的事件队列。然后这个事件会被事件循环传递给优先响应对象,即 Hit-Test View 。

    Hit-Test View 就是事件被触发时和用户交互的对象,寻找 Hit-Test View 的过程就叫做 Hit-Testing。

    参考文章:
    深入浅出iOS事件机制
    Responder一点也不神秘——iOS用户响应者链完全剖析
    iOS Events and Responder Chain

    相关文章

      网友评论

      本文标题:iOS事件处理

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