ios学习系列7--触摸事件 ios学习笔记
本篇是第七部分,关于触摸事件的一些内容。
ios的事件可分为三大类型:触摸事件,加速事件,远程事件。本章主要是触摸事件的相关内容。
-
响应者对象
在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件。我们称之为“响应者对象”。UIApplication、UIViewController、UIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件。
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;
-
-
UIView的触摸事件处理
UIView是UIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件(touches中存放的都是UITouch对象):
-
一根或者多根手指开始触摸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
当用户用一根触摸屏幕时,会创建一个与手指相关联的UITouch对象,该对象保存着跟手指相关的信息,比如触摸的位置、时间、阶段。当手指移动时,系统会更新同一个UITouch对象,使之能够一直保存该手指在的触摸位置,当手指离开屏幕时,系统会销毁相应的UITouch对象。
-
UIEvent
每产生一个事件,就会产生一个UIEvent对象,UIEvent是事件对象,记录事件产生的时刻和类型。
-
触摸事件
<1> 一次完整的触摸过程:
// 触摸开始 - (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;
4个触摸事件处理方法中,都有touches和event两个参数,在一次完整的触摸过程中,只会产生一个事件对象,4个触摸方法都是同一个event参数。根据touches中UITouch的个数可以判断出是单点触摸还是多点触摸。
<2> 事件的产生和传递
发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中。UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow)。主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件,这也是整个事件处理过程的第一步,找到合适的视图控件后,就会调用视图控件的touches方法来作具体的事件处理。响应者链条示意图:
如果view的控制器存在,就传递给控制器;如果控制器不存在,则将其传递给它的父视图。在视图层次结构的最顶级视图,如果也不能处理收到的事件或消息,则其将事件或消息传递给window对象进行处理。如果window对象也不处理,则其将事件或消息传递给UIApplication对象。如果UIApplication也不能处理该事件或消息,则将其丢弃。
-
手势识别
为了完成手势识别,必须借助于手势识别器UIGestureRecognizer。利用UIGestureRecognizer,能轻松识别用户在某个view上面做的一些常见手势。UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,使用它的子类才能处理具体的手势:
UITapGestureRecognizer(敲击) UIPinchGestureRecognizer(捏合,用于缩放) UIPanGestureRecognizer(拖拽) UISwipeGestureRecognizer(轻扫) UIRotationGestureRecognizer(旋转) UILongPressGestureRecognizer(长按)
具体使用:
// UITapGestureRecognizer的使用步骤如下: // 创建手势识别器对象 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init]; // 设置手势识别器对象的具体属性 // 连续敲击2次 tap.numberOfTapsRequired = 2; // 需要2根手指一起敲击 tap.numberOfTouchesRequired = 2; // 添加手势识别器到对应的view上 [self.iconView addGestureRecognizer:tap]; // 监听手势的触发 [tap addTarget:self action:@selector(tapIconView:)];
手势识别状态变化示意图: