iOS触摸事件处理和响应链

作者: jason_Yun | 来源:发表于2016-10-27 20:05 被阅读148次

    iOS中的事件

    用户与app交互的时候会产生各种各样的的事件,iOS中事件分为三大类型:1)触摸事件 ;2)加速计事件 ;3)远程控制事件

    在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件。我们称之为“响应者对象”。UIApplication、UIViewController、UIView都继承自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;

    UITouch

    用户用手指触摸屏幕时,会创建一个与手指相关联的UITouch对象。

    UITouch的作用:保存着跟手指相关的信息,比如触摸的位置、时间、阶段

    当手指移动时,系统会更新同一个UITouch对象,使之能够一直保存该手指在的触摸位置。

    当手指离开屏幕时,系统会销毁相应的UITouch对象

    提示:iPhone开发中,要避免使用双击事件!

    处理原理如下:

    1> 当用户点击屏幕时,会产生一个触摸事件,系统会将该事件加入到一个由UIApplication管理的事件队列中;

    2>UIApplication会从事件队列中取出最前面的事件进行分发以便处理,通常,先发送事件给应用程序的主窗口(UIWindow);

    3>主窗口会调用hitTest:withEvent:方法在视图(UIView)层次结构中找到一个最合适的UIView来处理触摸事件

    (hitTest:withEvent:其实是UIView的一个方法,UIWindow继承自UIView,因此主窗口UIWindow也是属于视图的一种)

    hitTest:withEvent:方法大致处理流程是这样的:首先调用当前视图的pointInside:withEvent:方法判断触摸点是否在当前视图内:

    ▶ 若pointInside:withEvent:方法返回NO,说明触摸点不在当前视图内,则当前视图的hitTest:withEvent:返回nil

    ▶ 若pointInside:withEvent:方法返回YES,说明触摸点在当前视图内,则遍历当前视图的所有子视图(subviews),调用子视图的

    注意:hitTest:withEvent:方法忽略隐藏(hidden=YES)的视图,禁止用户操作(userInteractionEnabled=NO)的视图,以及alpha级别小于0.01(alpha<0.01)的视图。

    这里ViewA包含ViewB和ViewC,ViewC中继续包含ViewD和ViewE。假设我们点击了viewE区域,则hit-test View判定过程如下:

    1. 触摸在A内部,所以需要检查B和C

    2. 触摸不在B内部,在C内部,所以需要检查D和E

    3. 触摸不在D内部,但在E内部,由于E已经是叶子了,所以判定到此结束

    消息处理过程

    在找到的那个视图里处理,处理完后根据需要,利用响应链nextResponder可将消息往下一个响应者传递。

    UIAppliaction <- UIWindow <- UIViewController <- UIView <- UIView

    【关键】:要理解的有三点:

    1、iOS判断哪个界面能接受消息是从View层级结构的父View向子View传递,即树状结构的根节点向叶子节点递归传递。

    2、hitTest和pointInside成对,且hitTest会调用pointInside。

    3、iOS的消息处理是,当消息被人处理后默认不再向父层传递。

    相关文章

      网友评论

        本文标题:iOS触摸事件处理和响应链

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