UIWindow 和 UIKit 中的控件因为继承了 UIView,所以也间接继承了 UIResponder 类,这些
类的实例都可以当作响应者。
第一响应者(First responder)
当前接受触摸的响应者对象被称为第一响应者,即表示当前该对象正在与用户交互,它
是响应者链的开端。
响应者链(Responder chain)
响应者链表示一系列的响应者对象。事件被交由第一响应者对象处理,如果第一响应者不
处理,事件被沿着响应者链向上传递,交给下一个响应者(
next responder)。一般来说,第
一响应者是个视图对象或者其子类对象,当其被触摸后事件被交由它处理,如果它不处理,
事件就会被传递给它的视图控制器对象(如果存在),然后是它的父视图(
superview)对
象(如果存在),以此类推,直到顶层视图。接下来会沿着顶层视图(
top view)到窗口
(
UIWindow 对象)再到程序(UIApplication 对象)。如果整个过程都没有响应这个事件,
该事件就被丢弃。一般情况下,在响应者链中只要由对象处理事件,事件就停止传递。但有
时候可以在视图的响应方法中根据一些条件判断来决定是否需要继续传递事件。
管理事件分发
视图对触摸事件是否需要作处回应可以通过设置视图的 userInteractionEnabled 属性。默认
状态为
YES,如果设置为 NO,可以阻止视图接收和分发触摸事件。除此之外,当视图被隐
藏(
setHidden:YES)或者透明(alpha 值为 0)也不会收事件。不过这个属性只对视图有效,
如果想要整个程序都步响应事件,可以调用
UIApplication 的
beginIngnoringInteractionEvents 方法来完全停止事件接收和分发。通过
endIngnoringInteractionEvents 方法来恢复让程序接收和分发事件。
如果要让视图接收多点触摸,需要设置它的 multipleTouchEnabled 属性为 YES,默认状
态下这个属性值为
NO,即视图默认不接收多点触摸。
了解触摸、事件和响应者之后,接下去学习如何处理用户的触摸事件。首先触摸的对象是
视图,而视图的类
UIView 继承了 UIRespnder 类,但是要对事件作出处理,还需要重写
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;
当手指接触屏幕时,就会调用 touchesBegan:withEvent 方法;
当手指在屏幕上移时,动就会调用 touchesMoved:withEvent 方法;
当手指离开屏幕时,就会调用 touchesEnded:withEvent 方法;
当触摸被取消(比如触摸过程中被来电打断),就会调用 touchesCancelled:withEvent 方
法。而这几个方法被调用时,正好对应了
UITouch 类中 phase 属性的 4 个枚举值。
上面的四个事件方法,在开发过程中并不要求全部实现,可以根据需要重写特定的方法。
对于这
4 个方法,都有两个相同的参数:NSSet 类型的 touches 和 UIEvent 类型的 event。其
中
touches 表示触摸产生的所有 UITouch 对象,而 event 表示特定的事件。因为 UIEvent 包含
了整个触摸过程中所有的触摸对象,因此可以调用
allTouches 方法获取该事件内所有的触
摸对象,也可以调用
touchesForVIew:或者 touchesForWindows:取出特定视图或者窗口上
的触摸对象。在这几个事件中,都可以拿到触摸对象,然后根据其位置,状态,时间属性做
逻辑处理。
例如: