在iOS中,事件被封装成 UIEvent对象,主要有以下属性
@property(nonatomic,readonly) UIEventType type; //事件类型
@property(nonatomic,readonly)UIEventSubtype subtype;
@property(nonatomic,readonly)NSTimeInterval timestamp;//事件产生时间
事件分为以下三类
1,触摸事件 UIEventTypeTouches
2,运动事件 UIEventTypeMotion
3,远程控制事件 UIEventTypeRemoteControl
在iOS中并不是所有的类都能处理接收并事件,只有继承自UIResponder类的对象(响应者对象)才能处理事件,我们常用的UIView、UIViewController、UIApplication都继承自UIResponder,它们都能接收并处理事件。
UIResponder 提供以下方法来处理事件
- 触摸事件
//一根或多根手指开始触摸view,系统会自动调用view下面的方法:
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
// 一根或者多根手指在view上移动时,系统会持续的自动调用view下面的方法:
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
//一根或者多根手指离开view,系统会自动调用view下面的方法:
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
//触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程,系统会自动调用view下面的方法
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
当用户用一根手指触摸屏幕时,会创建一个与手指相关联的 UITouch 对象,主要有以下属性:
@property(nonatomic,readonly,retain)UIWindow *window; //触摸产生时所处的窗口
@property(nonatomic,readonly,retain)UIView *view;//触摸产生时所处的视图
@property(nonatomic,readonly) NSUInteger tapCount;//点击次数
@property(nonatomic,readonly)NSTimeInterval timestamp;//触摸产生时间
@property(nonatomic,readonly)UITouchPhase phase;//触摸所处状态
- 运动事件
//运动开始
-(void)motionBegan:(UIEventSubtype)motionwithEvent:(UIEvent*)event
//运动结束
-(void)motionEnded:(UIEventSubtype)motionwithEvent:(UIEvent*)event
//运动被取消
-(void)motionCancelled:(UIEventSubtype)motionwithEvent:(UIEvent*)event
- 远程控制事件事件
//接收到远程控制消息
-(void)remoteControlReceivedWithEvent:(UIEvent*)event
触摸事件处理机制
对于UIView,有三种情况不接受触摸事件
- userInteractionEnable = NO;
- hidden = YES;;
- alpha = 0.0~0.01;
当发生触摸时,系统会封装一个事件,事件会加入到UIApplication事件队列,通常分发给应用程序主窗口(window)
主窗口会通过以下方法从视图结构寻找合适的视图
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
例如用户点击了 View E
寻找过程为
从 View A 的 Subview View B 与 View C 中寻找,
发现在View C 内,再从View D 与 View E中寻找
在View E内
因此,事件的传递过程为:UIApplication->Window->View A->View C->view E
事件的响应链 The Responder Chain
如果初始化对象(initial object)—— 即initial view 不处理事件(处理事件通过touches..方法响应),UIKit会将事件传递给responder chain的下一个responder。每个responder决定它是传递事件还是通过nextResponder方法传递给它的下一个responder。这个操作继续直到UIApplication,然后废弃。