Chapter 10 手势 iOS 8 -Swift Programming cookBook 读书笔记

本文深入探讨了iOS中对swipe(滑动)、pinch(捏)、pan(拖拽)、tap(点)、long-press(长按)和rotation(旋转)等六种手势进行检测的方法,包括创建手势识别、添加到view、处理方法调用、手势类型分类及实例应用,如旋转、拖动和长按操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

iOS可以对swipe(滑动), pinch(捏), pan(拖拽), tap(点), long-press(长按), and rotation(旋转)共6种手势进行检测。
手势识别必须驾到UIView的实例里面,一个view可以有多个手势识别。
基本步骤:

  1. 创建一个手势识别
  2. 添加到一个view上,用addGestureRecognizer
  3. 写一个方法,当手势发生的时候,运行这个方法。这个方法必须返回void,必须无参数或只接受一个UIGestureRecognizer的参数
  4. 当不需要手势的时候,移除掉,用removeGestureRecognizer

手势识别可以被分为2类:

  • 不连续的:当检测到手势的时候,结束检测,调用一次方法,比如,双击
  • 连续的:持续检测,不断调用方法,直到手势结束。比如旋转,手势开始于用户旋转时,结束于用户抬起手指。
    UIGestureRecognizer有一个属性叫state,不连续的和连续的手势有不同的state:
  • 不连续的:
    • UIGestureRecognizerStatePossible
    • UIGestureRecognizerStateRecognized:认出手势
    • UIGestureRecognizerStateFailed:手势失败
  • 连续的:
    • UIGestureRecognizerStatePossible
    • UIGestureRecognizerStateBegan
    • UIGestureRecognizerStateChanged
    • UIGestureRecognizerStateEnded
    • UIGestureRecognizerStateFailed
    • UIGestureRecognizerStateCancelled,比如在手势过程中,有一个电话打过来

10.1 检测Swipe(滑动)

用UISwipeGestureRecognizer,一次只能检测一个方向:

var swipeRecognizer: UISwipeGestureRecognizer!

    override func viewDidLoad() {
        super.viewDidLoad()
        swipeRecognizer = UISwipeGestureRecognizer(target: self, action: "handleSwipes:")
        //只会检测向左的手势
        swipeRecognizer.direction = .Left
        swipeRecognizer.numberOfTouchesRequired = 1
        view.addGestureRecognizer(swipeRecognizer)
    }

    func handleSwipes(sender: UISwipeGestureRecognizer) {
        if sender.direction == .Down {
            println("Down")
        }
        if sender.direction == .Left {
            println("Left")
        }
        if sender.direction == .Right {
            println("Right")
        }
        if sender.direction == .Up {
            println("Up")
        }

    }

10.2 旋转

是属于连续的手势,用UIRotationGestureRecognizer, 不需要关心被旋转物体本来的角度,因为旋转时返回的角度都是基于0的。是一个相对的角度。

    var helloWorldLabel = UILabel()
    var rotaionRecognizer: UIRotationGestureRecognizer!
    var rotationAngleInRadians = 0.0 as CGFloat

    helloWorldLabel.text = "Hello, World"
    helloWorldLabel.font = UIFont.systemFontOfSize(16)
    helloWorldLabel.sizeToFit()
    helloWorldLabel.center = view.center
    view.addSubview(helloWorldLabel)

    rotaionRecognizer = UIRotationGestureRecognizer(target: self, action: "handleRotation:")
    view.addGestureRecognizer(rotaionRecognizer)
func handleRotation(sender:UIRotationGestureRecognizer) {

        println("\(sender.rotation) \(rotationAngleInRadians)")

        helloWorldLabel.transform = CGAffineTransformMakeRotation(rotationAngleInRadians + sender.rotation)
        if sender.state == .Ended {
            rotationAngleInRadians += sender.rotation
        }

    }

如果要在模拟器上模拟,要按住option键。

10.3 检测Pan(拖动)

属于连续手势,在End状态的时候,可能取到的位置是一个nil值:

{
    var panGestureLabel: UILabel!
    var panGestureRecognizer: UIPanGestureRecognizer!
//pan gesture
        let labelFrame = CGRect(x: 0, y: 0, width: 150, height: 100)
        panGestureLabel = UILabel(frame: labelFrame)

        panGestureLabel.userInteractionEnabled = true
        panGestureLabel.text = "Pan Gesture"
        panGestureLabel.backgroundColor = UIColor.blackColor()
        panGestureLabel.textColor = UIColor.whiteColor()
        panGestureLabel.textAlignment = .Center
        panGestureRecognizer = UIPanGestureRecognizer(target: self, action: "handlePanGestures:")

        view.addSubview(panGestureLabel)
        panGestureRecognizer.minimumNumberOfTouches = 1
        panGestureRecognizer.maximumNumberOfTouches = 1
        panGestureLabel.addGestureRecognizer(panGestureRecognizer)
    }

    func handlePanGestures(sender: UIPanGestureRecognizer) {

        if sender.state != .Ended && sender.state != .Failed {
            let location = sender.locationInView(sender.view!.superview)
            sender.view?.center = location
        }
//        如果是多手指用这个
//        sender.locationOfTouch(<#touchIndex: Int#>, inView: <#UIView?#>)
    }

10.4 长按

用UILongPressGestureRecognizer, 有几个属性需要注意:

  • numberOfTapsRequired: 在启动这个手势需要的点击数目,tap的意思是放手指在屏幕上,然后离开,缺省是0
  • numberOfTouchesRequired:touch的手指数目
  • allowableMovement:手指在屏幕上移动的pixel的最大数目
  • minimumPressDuration:手势触发的最短按压时间
//长按
        dummyButton = UIButton.buttonWithType(.System) as! UIButton
        dummyButton.frame = CGRect(x: 0, y: 0, width: 72, height: 37)
        dummyButton.setTitle("My Button", forState: .Normal)

        longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "handleLongPressGestures:")
        longPressGestureRecognizer.numberOfTouchesRequired = 2
        //在识别的时候,容许有一些抖动
        longPressGestureRecognizer.allowableMovement = 100
        //要按多久
        longPressGestureRecognizer.minimumPressDuration = 1

        dummyButton.frame = CGRect(x: 100, y: 100, width: 100, height: 50)
        view.addGestureRecognizer(longPressGestureRecognizer)
        view.addSubview(dummyButton)
func handleLongPressGestures(sender: UILongPressGestureRecognizer) {

        if sender.numberOfTouches() == 2 {
            let touchPoint1 = sender.locationOfTouch(0, inView: sender.view)
            let touchPoint2 = sender.locationOfTouch(1, inView: sender.view)

            let midPointX = (touchPoint1.x + touchPoint2.x) / 2.0
            let midPointY = (touchPoint1.y + touchPoint2.y) / 2.0
            let midPoint = CGPoint(x: midPointX, y: midPointY)
            dummyButton.center = midPoint
        }

    }

10.5 检测tap 手势

用UITapGestureRecognizer,相关的属性:
- numberOfTapsRequired: 在启动这个手势需要的点击数目,tap的意思是放手指在屏幕上,然后离开,缺省是0
- numberOfTouchesRequired:touch的手指数目

10.6 检测Pinch(捏)手势

用UIPinchGestureRecognizer:

//Pinch
        let labelRect = CGRect(x: 200, y: 400, width: 50, height: 50)
        pinchLabel = UILabel(frame: labelRect)
        pinchLabel.backgroundColor = UIColor.blackColor()
        pinchLabel.userInteractionEnabled = true
        pinchGestureRecognizer = UIPinchGestureRecognizer(target: self, action: "handlePinches:")
        pinchLabel.addGestureRecognizer(pinchGestureRecognizer)

        view.addSubview(pinchLabel)
func handlePinches(sender: UIPinchGestureRecognizer) {
        if sender.state == .Ended {
            currentScale = sender.scale
        } else if sender.state == .Began && currentScale != 0.0 {
            sender.scale = currentScale
        }

        if sender.scale != CGFloat.NaN && sender.scale != 0.0 {
            sender.view!.transform = CGAffineTransformMakeScale(sender.scale, sender.scale)
        }
    }

10.7 检测屏幕边缘的拖动手势

检测用户的手从屏幕的一边移动到你的view里面。比如划出上面的notification center和下面的控制中心。

func handleScreenEdgePan(sender: UIScreenEdgePanGestureRecognizer){
if sender.state == .Ended{ displayAlertWithTitle("Detected",
          message: "Edge swipe was detected")
      }
}

init(coder aDecoder: NSCoder!) {
super.init(coder: aDecoder)
      /* Create the Pinch Gesture Recognizer */
screenEdgeRecognizer = UIScreenEdgePanGestureRecognizer(target: self, action: "handleScreenEdgePan:")
      /* Detect pans from left edge to the inside of the view */
      screenEdgeRecognizer.edges = .Left
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值