轻点、触摸和手势
1 简介
IOS系统能够检测到用户触摸到屏幕,并将触摸的动作传递给相应的应用处理者。其中简单介绍几个术语:
1)手势
手势是指从你用一个或多个手指接触屏幕时开始,直到手指离开屏幕为止所发生的所有事件,即手势是一组事件的集合。
2)触摸
触摸是指把手指放到ios设备的屏幕上,从屏幕上拖动或抬起的一种行为。手势中涉及的触摸数等于同时位于屏幕上的手指数量。
2 事件
2.1 概述
事件是当用户手指触击屏幕及在屏幕上移动时,系统不断发送给应用程序的对象。在iOS中,触摸由UITouch对象表示,事件由UIEvent对象表示。系统将事件按照特定的路径(响应者链)传递给可以对其进行处理的对象(事件响应者)。
2.2 事件响应者
响应者对象是可以响应事件并对其进行处理的对象。UIResponder是所有响应者对象的基类,它不仅为事件处理,而且也为常见的响应者行为定义编程接口。UIApplication、UIView、和所有从UIView派生出来的UIKit类(包括UIWindow)都直接或间接地继承自UIResponder类。
2.3 第一响应者
第一响应者是应用程序中当前负责接收触摸事件的响应者对象(通常是一个UIView对象),即用户当前正在交互的对象。UIWindow对象以消息的形式将事件发送给第一响应者,使其有机会首先处理事件。如果第一响应者没有进行处理,系统就将事件(通过消息)传递给响应者链中的下一个响应者,看看它是否可以进行处理。
2.4 响应者链
响应者链是一个响应者对象的连接序列,事件或动作消息(或菜单编辑消息)依次传递。它允许响应者对象把事件处理的职责转交给其它更高层的对象。应用程序通过向上传递一个事件来查找合适的处理对象。在响应者链中的某一个响应者,若能响应被传递的事件,那么该事件就不会向下一级的响应者传递;若不能响应某事件,则将此事件向下一级传递。
2.4.1 初始响应者
事件首先会传递给UIApplication对象,接下来会传递给应用程序的UIWindow。UIWindow会选择一个初始响应者来处理事件。其中初始响应者会按照下面的方式选择:
-
触摸事件
当这种事件发生时,UIWindow对象会确定用户触摸的视图(UIView)。若被触摸的视图有能处理事件的手势识别器,那么该手势识别器作为初始响应者;若没有相应的手势识别器,那么被触摸的视图作为初始响应者。
-
摇晃事件或远程遥控设备的事件
那么第一响应者作为初始响应者。
2.4.2 触摸事件的传递顺序
响应者链处理原则:
-
当在第一响应者对象上产生事件或动作消息时,则将事件或动作消息传递给第一响应者,若其不处理事件,则将事件传递给它的视图控制器(如果它有的话);如果没有一个视图控制器,就传递给它的父视图;
-
如果一个视图或者它的视图控制器不能处理这个事件或动作消息,它将传递给该视图的父视图;
-
在这个视图层次中的每个后续的父视图遵循上述的模式,如果它不能处理这个事件或动作消息的话;
-
最顶层的视图如果不能处理这个事件或动作消息,就传递给UIWindow对象来处理;
-
如果UIWindow 对象不能处理,就传给单件应用程序对象UIApplication。
如果应用程序对象也不能处理这个事件或动作消息,将抛弃它。
注意:父视图是指当前视图所在的容器,是指一个UIView对象。
图 1
2.5 转发事件:保持响应者链的活动状态
如果某个对象截获了无法处理的事件,就需要手动地将该对象继续向下传递。其传递的方法就是在下一个响应者上钓用相同的方法。
super.viewDidLoad()
let ve = UISwipeGestureRecognizer(target: self, action: "Vo:")
view.addGestureRecognizer(ve)
}
func Vo(recognizer:UIGestureRecognizer)
{
}
3 手势响应
3.1 多点触控体系结构
由于手势是沿着响应者链传递,这意味着响应者链上的对象需要包含代码来处理相应的手势,既我们可以将代码嵌入UIView子类中,也可以将代码嵌入UIViewController中。
-
如果视图需要根据用户的触摸对自己执行某些操作,那么代码可能属于定义该视图的类。
-
若当正在处理的手势影响正在触摸的多个对象时,该手势代码实际上属于相关的视图控制器。
3.2 4个手势通知方法
当触摸了屏幕时,就会调用相应某个窗口或是视图的通知方法,其中通知方法有:
-
当一个或多个手指触碰屏幕时,系统将调用touchesBegan方法;
-
当一个或多个手指在屏幕上移动时,系统将调用touchesMoved方法;
-
当一个或多个手指离开屏幕时,系统将调用touchesEnded方法;
-
当触摸序列被诸如电话呼入这样的系统事件所取消时,系统将调用touchesCancelled方法;
如:
let touch = event?.allTouches()!.first
let touchNum = touch?.tapCount ; //手指的触摸次数
let eventNUm = event?.allTouches()?.count; //触摸手指的数量
}
4 手势识别器
4.1 UIGestureRecognizer介绍
iOS系统在3.2以后,为方便开发这使用一些常用的手势,提供了UIGestureRecognizer类。手势识别UIGestureRecognizer类是个抽象类,下面的子类是具体的手势,开发这可以直接使用这些手势识别。
-
UITapGestureRecognizer:Tap(点一下)
-
UIPinchGestureRecognizer:Pinch(二指往內或往外拨动,平时经常用到的缩放)
-
UIRotationGestureRecognizer:Rotation(旋转)
-
UISwipeGestureRecognizer:Swipe(滑动,快速移动)
-
UIPanGestureRecognizer:Pan(拖移,慢速移动)
-
UILongPressGestureRecognizer:LongPress(长按)
4.2 使用手势(代码)
使用手势很简单,分为两步:
-
创建手势实例。当创建手势时,指定一个回调方法,当手势开始,改变、或结束时,回调方法被调用。
-
添加到需要识别的View中。每个手势只对应一个View,当屏幕触摸在View的边界内时,如果手势和预定的一样,那就会回调方法。
ps:一个手势只能对应一个View,但是一个View可以有多个手势。
如:
2 super.viewDidLoad()
3 let ve = UISwipeGestureRecognizer(target: self, action: "Vo:")
4 view.addGestureRecognizer(ve)
5 }
6 func Vo(recognizer:UIGestureRecognizer)
7 {
8 }
4.3 使用手势(Xcode)
可以借助storyboard使用更加简单,也分为两步:
-
创建手势:直接从对象库中拖动一个GestureRecognizer对象到视图中。
-
指定响应方法:指定Send Actions标签中的selector属性。