美文网首页
事件传递和响应机制

事件传递和响应机制

作者: hou_blog | 来源:发表于2018-04-14 13:58 被阅读0次

    iOS 事件传递和响应机制

    一.概述

    APPs通过responder objects来接收和处理点击事件,responder

    Object是UIResponder类的实例。同时UIView,UIViewController,UIApplication

    也是UIResponder类的子类。

    事件的传递过程就是寻找first responder的过程,传递过程是从父控件到子控件逐层寻找第一响应者(UIApplication-> window->最合适的view)。找到firstResponder之后开始进行事件响应的过程,也就是说响应链的这顺序正好和事件的传递顺序相反,从子控件沿着响应链一直到响应链末端的父控件。

    二. 响应链的传递过程

            1.响应链的传递过程如下图:

    下图展示一个简易的APP,包含UILabel, UITextFileld, UIButton,UIView,UIViewController。如图示,响应链从上向下传递,传递到能响应的层级截止,如均无发响应这个事件,相当于系统放弃该事件。

    Figure 1-1

    2.响应链中的事件处理方法

    系统为UIView触摸事件处理提供了四个方法

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

    Tells this object that one or more new touches occurred in a view or window.

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

    Tells the responder when a system event (such as a system alert) cancels a touch sequence.

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

    Tells the responder when one or more touches associated with an event changed.

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

    Tells the responder when one or more fingers are raised from a view or window. 注意:如果是UIVIew的触摸事件需要自定义继承于UIView的子类,在子类中写这四个方法。如果是UIViewController的触摸事件直接在viewController中重写这四个方法就可以了。

    三.寻找事件的firstResponder

    1.具体步骤

    点击屏幕,发生点击事件,UIKIt开始处理点击事件,事件传递方向UIApplication->keyWindow->viewController->rootView->view->subView,按照事件传递方向寻找最合适的响应者,firstResponder。下面详细介绍fUIView的irstResponder寻找过程。

    (1)首先判断keyWindow是否能响应触摸事件或者说触摸事件是否在keyWindow范围内,如果不在则直接放弃后续查找

    (2)UIKit通过遍历view hierarchy寻找the deepest subview作为firstResponder

    下图是官方文档提供的解释

    Figure 1-2

    (3)view hierarchy的遍历是采用倒叙的形式,从rootView的子控件开始遍历

    例如:rootView包含三个视图,view1,view2,view3,其中view2又包含三个子视图subView1,subView2,subView3则遍历顺序是(本例子前提是所有view的- pointInside:withEvent:方法均返回YES,各个view的布局重叠)

    rootView->view3->view2->subView3->subView2->subView1->view1

    其中即使父控件符合响应者的要求,同样要遍历子控件寻找最合适的响应者。但是如果父控件不符合响应者要求(pointInside方法返回NO),则子控件不再遍历

    2.依赖方法详解

    (1)- (BOOL)pointInside:(CGPoint)point  withEvent:(UIEvent *)event;下图是官方文档的解释

    返回YES代表点击的point在当前遍历view的范围内

    Figure 1-3

    (2)- (UIView *)hitTest:(CGPoint)point  withEvent:(UIEvent *)event;下方图片是关于该方法的文档解释

    Figure 1-4

    简要介绍一下,

          (1)接收到点击事件,开始遍历视图,每个视图的hitTest方法都会调用pointInside:withEvent方法,该方法返回YES则继续执行hitTest方法

          (2)通过override pointInside:withEvent方法让其return NO,则当前视图及其子视图放弃点击事件的处理,交给其父视图完成

         (3)当透明度在0--0.01之间或者hidden属性被赋值YES时,这个方法不再调用

    四.代码示例

    UIView不能接受传递事件的三种情况

    2.事件传递过程

    3.用到的方法,使用方式

    4.示例

    (1)响应链论证

    (2)修改响应链

    5.Question and Summary

    相关文章

      网友评论

          本文标题:事件传递和响应机制

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