城之内

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一、关于事件传递一些基础知识

1、UIView类是UIResponder的一个子类,因此能够接收用户和视图内容交互 时产生的触摸事件。触摸事件从发生触摸的视图开始,沿着响应者链进行传 递,直到最后被处理。

     视图本身就是响应者,是响应者链的参与者,因此可以 收到所有关联子视图派发给它们的触摸事件。 

2、在缺省情况下,视图每次只响应一个触摸动作。如果用户将第二个手 指放在屏幕上,系统会忽略该触摸事件,而不会将它报告给视图对象。如果您 希望在视图的事件处理器方法中跟踪多点触摸手势,则需要重新激活多点触摸 事件,具体方法是将视图的multipleTouchEnabled属性声明设置为 YES。 比如标签和图像视图,在初始状态下完全禁止事件处理。您可以通 过改变视图的userInteractionEnabled属性值来控制视图是否可以对事 件进行处理。当某个耗时很长的操作被挂起时,您可以暂时将这个属性设置为 NO 

3、在处理触摸事件时,UIKit会通过UIView的hitTest:withEvent:和 pointInside:withEvent:方法来确定触摸事件是否发生在指定的视图 上 

 

二、事件处理 

1、事件和触摸

在iPhone OS中,触摸动作是指手指碰到屏幕或在屏幕上移动,它是一个多点 触摸序列的一部分。比如,一个pinch-close手势就包含两个触摸动作:即屏 幕上的两个手指从相反方向靠近对方。一些单指手势则比较简单,比如触击、 双击、或轻拂(即用户快速碰擦屏幕)。应用程序也可以识别更为复杂的手 势,举例来说,如果一个应用程序使用具有转盘形状的定制控件,用户就需要 用多个手指来“转动”转盘,以便进行某种精调。

事件是当用户手指触击屏幕及在屏幕上移动时,系统不断发送给应用程序的对 象。事件对象为一个多点触摸序列中所有触摸动作提供一个快照,其中最重要 的是特定视图中新发生或有变化的触摸动作。一个多点触摸序列从第一个手指 碰到屏幕开始,其它手指随后也可能触碰屏幕,所有手指都可能在屏幕上移 动。当最后一个手指离开屏幕时,序列就结束了。在触摸的每个阶段,应用程 序都会收到事件对象。

触摸信息有时间和空间两方面,时间方面的信息称为阶段(phrase),表示触 摸是否刚刚开始、是否正在移动或处于静止状态,以及何时结束—也就是手指 何时从屏幕举起(参见图3-1)。触摸信息还包括当前在视图或窗口中的位置 信息,以及之前的位置信息(如果有的话)。当一个手指接触屏幕时,触摸就 和某个窗口或视图关联在一起,这个关联在事件的整个生命周期都会得到维 护。如果有多个触摸同时发生,则只有和同一个视图相关联的触摸会被一起处 理。类似地,如果两个触摸事件发生的间隔时间很短,也只有当它们和同一个 视图相关联时,才会被处理为多触击事件。

图3-1 多点触摸序列和触摸阶段

在iPhone OS中,一个UITouch对象表示一个触摸,一个UIEvent对象表示 一个事件。事件对象中包含与当前多点触摸序列相对应的所有触摸对象,还可 以提供与特定视图或窗口相关联的触摸对象(参见图3-2)。在一个触摸序列

 page70image5712 page70image5872

发生的过程中,对应于特定手指的触摸对象是持久的,在跟踪手指运动的过程 中,UIKit会对其进行修改。发生改变的触摸属性变量有触摸阶段、触摸在视图 中的位置、发生变化之前的位置、以及时间戳。事件处理代码通过检查这些属 性的值来确定如何响应事件。 

图3-2 UIEvent对象及其UITouch对象间的关系

系统可能随时取消多点触摸序列,进行事件处理的应用程序必须做好正确响应 的准备。事件的取消可能是由于重载系统事件引起的,电话呼入就是这样的例 子。 

2、事件的传递和处理

界面响应消息机制分两块

(1)首先在视图的层次结构里找到能响应消息的那个视图。(就是查找第一响应者,查找顺序是UIApplication -> UIWindow -> UIView)

 

 系统将事件按照特定的路径传递给可以对其进行处理的对象。 当用户触摸设备屏幕时,iPhone OS会将它识别为一组 触摸对象,并将它们封装在一个UIEvent对象中,放入当前应用程序的事件 队列中。事件对象将特定时刻的多点触摸序列封装为一些触摸对象。负责管理 应用程序的UIApplication单件对象将事件从队列的顶部取出,然后派发给 其它对象进行处理。 它会将事件发送给应用程序的键盘焦点窗口 —即拥有当前用户事件焦点的窗口,然后代表该窗口的UIWindow对象再将它发送给第一响应者进行处理 。

如何找到第一响应者呢?应用程序通过触碰测试(hit-testing)来寻找事件的第一响应者,即通过递归 调用视图层次中视图对象的hitTest:withEvent:方法来确认发生触摸的 子视图。触摸对象的整个生命周期都和该视图互相关联,即使触摸动作最终移动到该视图区域之外也是如此。 

(2)然后在找到的视图里处理消息。(找到第一响应者后,要确定它是否要处理,如果不处理会沿着响应者链传递传递下去) 

响应者对象和响应者链

响应者对象是可以响应事件并对其进行处理的对象。UIResponder是所有响应者对象的基类,它不仅为事件处理,而且也为常见的响应者行为定义编程接 口。UIApplication、UIView、和所有从UIView派生出来的UIKit类(包 括UIWindow)都直接或间接地继承自UIResponder类。

第一响应者是应用程序中当前负责接收触摸事件的响应者对象(通常是一个 UIView对象)。UIWindow对象以消息的形式将事件发送给第一响应者,使 其有机会首先处理事件。如果第一响应者没有进行处理,系统就将事件(通过 消息)传递给响应者链中的下一个响应者,看看它是否可以进行处理。

响应者链是一系列链接在一起的响应者对象,它允许响应者对象将处理事件的 责任传递给其它更高级别的对象。随着应用程序寻找能够处理事件的对象,事 件就在响应者链中向上传递。响应者链由一系列“下一个响应者”组成,其顺序 如下:

  1. 第一响应者将事件传递给它的视图控制器(如果有的话),然后是它的 父视图。

  2. 类似地,视图层次中的每个后续视图都首先传递给它的视图控制器(如 果有的话),然后是它的父视图。

  3. 最上层的容器视图将事件传递给UIWindow对象。

  4. UIWindow对象将事件传递给UIApplication单件对象。 如果应用程序找不到能够处理事件的响应者对象,则丢弃该事件。 

通过以下4个函数传递

1 touchesBegan:withEvent:
2 touchesMoved:withEvent:
3 touchesEnded:withEvent:
4 touchesCancelled:withEvent: 

posted on 2015-03-13 10:40  城之内  阅读(319)  评论(0编辑  收藏  举报