UIGestureRecognizer介绍
前言:部分内容来自网络,感谢原作者的分享。
手势识别在iOS上非常重要,手势操作移动设备的重要特征,极大的增加了移动设备使用便捷性。
iOS系统在3.2以后,为方便开发这使用一些常用的手势,提供了UIGestureRecognizer类。手势识别UIGestureRecognizer类是个抽象类,下面的子类是具体的手势,开发这可以直接使用这些手势识别。
• UITapGestureRecognizer
• UIPinchGestureRecognizer
• UIRotationGestureRecognizer
• UISwipeGestureRecognizer
• UIPanGestureRecognizer
• UILongPressGestureRecognizer
上面的手势对应的操作是:
• Tap(轻击)
• Pinch(捏合:二指往內或往外拨动,平时经常用到的缩放)
• Rotation(旋转)
• Swipe(轻扫:滑动,快速移动)
• Pan (拖拽:拖移,慢速移动)
• LongPress(长按)
UIGestureRecognizer的继承关系如下:
为了识别手势,需要将Gesture Recognizers关联到其检测触摸事件的view上,可以使用UIView的addGestureRecognizer:方法将手势识别器绑定到视图上。Gesture Recognizers在触摸事件处理流程中,处于观察者的角色,其不是view层级结构的一部分,所以也不参与responder chain。在将触摸事件发送给hit-test view之前,系统会先将触摸事件发送到hit-test view上绑定的或hit-test view父视图(superview)上绑定的Gesture Recognizers上。其流程大概如下图所示:
注:图中view与Gesture Recognizer的关系是,Gesture Recognizer关联在view或view的superview(可能多级)上。
UIGestureRecognizer API
1、初始化
init(target target: AnyObject?,
action action: Selector)
参数:
target:当手势触发时,动作消息的接收者,nil标示无效
action:接收者target执行的方法
说明:当初始化完成时可用用addTarget方法添加其他的target-action组
2、为手势识别器(gesture-recoginzer)添加一个目标及动作
func addTarget(_ target: AnyObject,
action action: Selector)
参数:
target:当手势触发时,动作消息的接收者,nil标示无效
action:接收者target执行的方法
3、删除一个目标及动作
func removeTarget(_ target: AnyObject?,
action action: Selector)
参数:
target:当手势触发时,动作消息的接收者,nil标示从接收者移除所有目标
action:接收者target执行的方法,null标示移除所有action
获取手势触摸和位置
4、获得手势在视图中的本地坐标
func locationInView(_ view: UIView?) -> CGPoint
参数:
view:手势发生的地方,nil表示window
返回值:
在本地坐标系统中的一个点,该点识别手势的位置。如果参数为nil,该方法返回以窗口为基础坐标系统中的手势位置。
5、在本地坐标系统中的一个点,该点识别手势的位置
func locationOfTouch(_ touchIndex: Int,
inView view: UIView?) -> CGPoint
参数:
touchIndex:一个私有数组中UITouch对象的索引,该数组有接收器持有。touch对象代表当前触摸的手势。
view:手势发生的地方,nil表示window
返回值:
在本地坐标系统中的一个点,该点识别手势的位置。如果参数为nil,该方法返回以窗口为基础坐标系统中的手势位置。
6、触点数量
func numberOfTouches() -> Int
返回值:
接收器持有的私有数组中的UITouch对象的数量,每一个对象代表一个触摸在当前的手势中。
获得recognizer的state和view
1、 手势识别的状态
var state: UIGestureRecognizerState { get }
状态定义如下:
enum UIGestureRecognizerState : Int
{
//手势还没开始,但能接收触摸事件,这是默认状态
case Possible
//连续的手势开始,并在下一个运行循环周期发送消息
case Began
//连续的手势开始改变并,在下一个运行循环周期发送消息
case Changed
//连续手势结束,并在下一个循环周期发送消息并且重置状态为Possible
case Ended
//连续手势被取消,并在下一个循环周期发送消息并且重置状态为Possible
case Cancelled
//手势识别器已经获得多点触摸序列,它无法识别手势,不发送消息,识别器 重置状态为Possible.
case Failed
//已经被识别,并在下一个循环周期发送消息并且重置状态为Possible
static var Recognized: UIGestureRecognizerState { get }
}
2、 手势识别器所附加的视图
var view: UIView? { get }
说明:用UIView的方法addGestureRecognizer添加手势。
3、 手势识别是否启用
var enabled: Bool
说明:禁用手势识别器,它会不接收触摸事件。默认值为true,如果改变此属性为false,当一个手势识别器正在识别一个手势的时候,识别器会改变它的状态为cancellded状态
取消和延迟触摸
1、 取消触摸消息发送给view,默认为true
var cancelsTouchesInView: Bool
说明:表示当Gesture Recognizers识别到手势后,会向hit-test view发送 touchesCancelled:withEvent:消息来取消hit-test view对此触摸序列的处理,这样只有Gesture Recognizers能响应此触摸序列,hit-test view不再响应。如果为NO,则不发送touchesCancelled:withEvent:消息给hit-test view,这样会使Gesture Recognizers和hit-test view同时响应触摸序列。
2、 延迟触摸的开始状态
var delaysTouchesBegan: Bool(默认为false)
说明:表示触摸序列开始时,而手势识别器还未识别出此手势时,touch事件会同时发向hit-test view,这样在手势识别器还未识别出此手势,hit-test view同时也可