本文系转载,原文地址为iOS触摸事件全家桶
UITouch -- 源起触摸
- 一个手指一次触摸屏幕,就对应生成一个UITouch对象。多个手指同时触摸,生成多个UITouch对象。
- 多个手指先后触摸,系统会根据触摸的位置判断是否更新同一个UITouch对象。若两个手指一前一后触摸同一个位置(即双击),那么第一次触摸时生成一个UITouch对象,第二次触摸更新这个UITouch对象(UITouch对象的 tap count 属性值从1变成2);若两个手指一前一后触摸的位置不同,将会生成两个UITouch对象,两者之间没有联系。
- 每个UITouch对象记录了触摸的一些信息,包括触摸时间、位置、阶段、所处的视图、窗口等信息。
//触摸的各个阶段状态
//例如当手指移动时,会更新phase属性到UITouchPhaseMoved;手指离屏后,更新到UITouchPhaseEnded
typedef NS_ENUM(NSInteger, UITouchPhase) {
UITouchPhaseBegan, // whenever a finger touches the surface.
UITouchPhaseMoved, // whenever a finger moves on the surface.
UITouchPhaseStationary, // whenever a finger is touching the surface but hasn't moved since the previous event.
UITouchPhaseEnded, // whenever a finger leaves the surface.
UITouchPhaseCancelled, // whenever a touch doesn't end but we need to stop tracking (e.g. putting device to face)
};
手指离开屏幕一段时间后,确定该UITouch对象不会再被更新将被释放。
UIEvent --- 事件的真身
- 触摸的目的是生成触摸事件供响应者响应,一个触摸事件对应一个UIEvent对象,其中的 type 属性标识了事件的类型(之前说过事件不只是触摸事件)。
@property(nonatomic,readonly) UIEventType type API_AVAILABLE(ios(3.0));
typedef NS_ENUM(NSInteger, UIEventType) {
UIEventTypeTouches,
UIEventTypeMotion,
UIEventTypeRemoteControl,
UIEventTypePresses API_AVAILABLE(ios(9.0)),
UIEventTypeScroll API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos) = 10,
UIEventTypeHover API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos) = 11,
UIEventTypeTransform API_AVAILABLE(ios(13.4), tvos(13.4)) API_UNAVAILABLE(watchos) = 14,
};
- UIEvent对象中包含了触发该事件的触摸对象的集合,因为一个触摸事件可能是由多个手指同时触摸产生的。触摸对象集合通过 allTouches 属性获取。
@property(nonatomic, readonly, nullable) NSSet <UITouch *> *allTouches;
UIResponder -- 一切为了满足它的野心
- 每个响应者都是一个UIResponder对象,即所有继承自UIResponder的对象,本身都具备响应事件的能力。因此以下类的实例都是响应者:
UIView
UIViewController
UIApplication
AppDelegate
- 响应者之所以能响应事件,因为其提供了4个处理触摸事件的方法:
//手指触碰屏幕,触摸开始
- (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:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
这几个方法在响应者对象接收到事件的时候调用,用于做出对事件的响应。关于响应者何时接收到事件以及事件如何沿着响应链传递将在下面章节说明。
网友评论