UIGestureRecognizer手势识别详解

来源:互联网 发布:百度seo推广怎么收费 编辑:程序博客网 时间:2024/05/21 10:55

 iOS应用开发过程,合理的使用手势识别功能来响应用户的操作,能够很好提升用户体验,为App增色。下面对UIGestureRecognizer手势进行一个比较全面的描述:  

    

       1、UIGestureRecognizer介绍

            UIGestureRecognizer是手势识别的一个抽象类,没法直接使用。好心的苹果大神们已经为我们实现了常用的一些手势识别子类,具体列表如下:

  • UITapGestureRecognizer                               
  • UIPinchGestureRecognizer                            
  • UIRotationGestureRecognizer                        
  • UISwipeGestureRecognizer                            
  • UIPanGestureRecognizer                               
  • UIScreenEdgePanGestureRecognizer(iOS7.0以后)           
  • UILongPressGestureRecognizer                    

       1.1、UITapGestureRecognizer介绍
             用以识别用户使用单指或多指在某个View中点击一次或多次的动作。UITapGestureRecognizer除了包含继承自父类的属性外,还有两个自有属性:
             numberOfTapsRequired:          表示点击的次数,当连续点击次数未达到指定数量时,不作响应,默认值为1。
             numberOfTouchesRequired:    表示需同时点击的手指数量,默认值为1。
       1.2、UIPinchGestureRecognizer介绍
             用以识别用户使用两指在某个View中向外或向内滑动动作,平时多用于缩放。UIPinchGestureRecognizer除了包含继承自父类的属性外,还有两个自有属性:
             scale:表示缩放率
             velocity:表示缩放率对应的每秒速率(只读)
        1.3、UIRotationGestureRecognizer介绍
             用以识别用户使用两指在某个View中旋转动作。UIRotationGestureRecognizer除了包含继承自父类的属性外,还有两个自有属性:
             rotation:  表示旋转的弧度
             velocity:表示旋转弧度对应的每秒速率(只读)
         1.4、UISwipeGestureRecognizer介绍
             用以识别用户使用手指在某个View中的滑动动作,即快速移动。UISwipeGestureRecognizer除了包含继承自父类的属性外,还有两个自有属性:
             direction:表示滑动方向,向左、向右、向上、向下共四个方向
             numberOfTouchesRequired:表示需同时滑动的手指数量,默认值为1。
         1.5、UIPanGestureRecognizer介绍
             用以识别用户使用单指或多指在某个View中慢速移动动作。UIPanGestureRecognizer除了包含继承自父类的属性外,还有两个自有属性:
             minimumNumberOfTouches:表示最小手指数量,默认值为1
      maximumNumberOfTouches:表示最大手指数量,默认值为无符号整型的最大值
    1.6、UIScreenEdgePanGestureRecognizer介绍
      继承自UIPanGestureRecognizer,只是需要指定拖动动作的起始点距离屏幕边缘的位置。UIScreenEdgePanGestureRecognizer除了包含继承自父类的属性外,还有一个自有属性:
      edges:手势起始的位置区域
    1.7、UILongPressGestureRecognizer介绍
      用以识别用户使用单指或多指在某个View中长按的动作。UILongPressGestureRecognizer除了包含继承自父类的属性外,还有四个自有属性:
      minimumPressDuration:最短按下的时间,默认值为0.5秒。
      numberOfTouchesRequired:表示需同时滑动的手指数量,默认值为1。
      numberOfTapsRequired:表示点击的次数,默认值为1。
      allowableMovement:表示长按过程中手指允许移动的长度,计量单位为像素点,默认值为10像素点

       2、UIGestureRecognizer使用通用步骤

             UIGestureRecognizer使用非常简单,只需要两步即可完成:

             A、创建UIGestureRecognizer使用实例,指定对应的回调方法,此处以UITapGestureRecognizer为例说明

                  

[plain] view plain copy
  1.  //创建UITapGestureRecognizer实例对象  
[plain] view plain copy
  1. let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "handlePan:")  

[plain] view plain copy
  1.  //实现回调方法  
[plain] view plain copy
  1. func handlePan(sender: UITapGestureRecognizer) {  
  2.     print("get tap gesture")  
  3. }  
             B、将UIGestureRecognizer实例对象添加进指定的View。一个手势只能对应一个View,但是一个View可以有多个手势

                 

[plain] view plain copy
  1. self.view.addGestureRecognizer(tapGesture)  
                 多个View,只需向同一个View中继续添加UIGestureRecognizer实例对象即可

                 

[plain] view plain copy
  1. self.view.addGestureRecognizer(rotationGesture)  

         3、自定义手势

              自定义手势需要继承UIGestureRecognizer类,并实现下面的方法

             

[plain] view plain copy
  1. - touchesBegan:withEvent:     //手势开始,当用户单指或多指触碰到屏幕  
  2. - touchesMoved:withEvent:     //手势移动,当用户单指或多指在屏幕上移动  
  3. - touchesEnded:withEvent:     //手势结束,当用户手指离开屏幕  
  4. - touchesCancelled:withEvent: //手势取消,如系统内存不足导致的取消等  
        下面的例子为自定义的Tap手势实现代码,仅供学习之用

            

[plain] view plain copy
  1. //  
  2. //  CustomTapGestureRecoginizer.swift  
  3. //  Gest  
  4. //  
  5. //  Created by jimi on 15/12/28.  
  6. //  Copyright © 2015年 jimi. All rights reserved.  
  7. //  
  8.   
  9. import UIKit  
  10. import UIKit.UIGestureRecognizerSubclass  
  11.   
  12. class CustomTapGestureRecoginizer: UIGestureRecognizer {  
  13.     var numberOfTapsRequired: Int = 1  
  14.     var numberOfTouchesRequired: Int = 1  
  15.       
  16.     var firstLocation: CGPoint = CGPointZero  
  17.       
  18.     override init(target: AnyObject?, action: Selector) {  
  19.         super.init(target: target, action: action)  
  20.     }  
  21.       
  22.     override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent) {  
  23.         super.touchesBegan(touches, withEvent: event)  
  24.         if touches.count != self.numberOfTouchesRequired {  
  25.             self.state = UIGestureRecognizerState.Failed  
  26.         }  
  27.           
  28.         if let touch: UITouch = touches.first {//得到手指点击的起始位置  
  29.             self.firstLocation = touch.locationInView(self.view)  
  30.         }  
  31.     }  
  32.       
  33.     override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent) {  
  34.         super.touchesMoved(touches, withEvent: event)  
  35.         if let touch: UITouch = touches.first {  
  36.             let currentPoint: CGPoint = touch.locationInView(self.view)  
  37.             if abs(currentPoint.x - self.firstLocation.x) >= 10 {//当手势有移动时,判断手势异动距离是否已经大于10个点,如果大于10个点即为非点击事件了  
  38.                 self.state = UIGestureRecognizerState.Failed  
  39.             }  
  40.         }  
  41.     }  
  42.       
  43.     override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent) {  
  44.         super.touchesEnded(touches, withEvent: event)  
  45.         self.firstLocation = CGPointZero  
  46.           
  47.         self.state = UIGestureRecognizerState.Ended       //手势识别成功,将状态标记为识别成功  
  48.     }  
  49.       
  50.     override func touchesCancelled(touches: Set<UITouch>, withEvent event: UIEvent) {  
  51.         super.touchesCancelled(touches, withEvent: event)  
  52.         self.firstLocation = CGPointZero  
  53.     }  
  54. }  

         4、UIGestureRecognizer进阶
         4.1 UIGestureRecognizer状态说明

         此处借用一下苹果官方文档的图片,:)

        

         图片左半边是离散手势(如点击事件)的状态变迁图,右半边是连续事件(如滑动)状态变迁图。任何事件都是从Possible(可能的)的状态开始,经过必要的事件之后,转变成Failed(失败)、Canceled或Recognized(可识别)状态,即手势识别结束。

  • 离散事件缺少中间的Changed(正在变化的)中间状态,直接从事件的Began到结束状态Failed或Recognized
  • 连续事件中的Changed不停的标记当前正在发生的事件的状态,如滑动事件,会一直记录当前手势移动的位置,对应于代码中touchesMoved
  • 当手指离开屏幕,表示手势事件结束。此时需要识别结束后的事件是否满足既定的手势识别条件。如移动的距离和速度等是否满足要求,如果满足即表示识别成功(Recognized),否则表示识别失败(Failed);若中途遭遇其他系统事件中断(如内存不足),即表示手势识别事件被取消(Canceled)。

         4.2 多手势识别顺序问题

              前面我们已经简单提到过,同一个View可以包含多个手势,但是一个手势只能对应一个View。如果在同一个View中包含了多个手势,在iOS系统默认情况下,没有任何顺序可言,这就是通常所说的手势冲突问题。好在苹果允许我们修改手势的部分默认行为方式:

  • 两个具有部分包含关系的手势,可以通过指定识别顺序来解决手势冲突问题;
            如:panRecognizer.requireGestureRecognizerToFail(swipeRecognizer)

rotationGesture.requireGestureRecognizerToFail(panGesture)

  • 可以指定同时识别的两个手势
           这个需要实现手势代理方法gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:方法,在该方法中返回YES(true)即可
  • 指定两个手势之间的阻止关系,如手势A响应时,不响应手势B,但是手势B响应时,需要响应手势A

            panRecognizer.canPreventGestureRecognizer(pinchGestureRecognizer)   

0 0