如何实现velocityInView:用于自定义手势识别器?

我正在实现一个自定义的UIGestureRecognizer子类。

我想实现velocityInView:就像UIPanGestureRecognizer做的一样。 但我不知道如何去做。 我如何计算以点/秒为单位的速度?

首先,如果你使用的是Swift,你将需要创build一个Bridging Header和#import <UIKit/UIGestureRecognizerSubclass.h>这样你就可以覆盖UIGestureRegoniser触摸开始/移动/取消/结束的方法。 如果您使用Objective-C,只需将该import语句放在.h或.m文件中即可。

其次,一旦你创build了你的UIGestureRecogniser子类,你就需要这些variables:

 private lazy var displayLink: CADisplayLink = { let link = CADisplayLink(target: self, selector: Selector("timerCalled")) link.addToRunLoop(NSRunLoop.currentRunLoop(), forMode: NSRunLoopCommonModes) return link }() private var previousTouchLocation: CGPoint? private var currentTouchLocation : CGPoint? private var previousTime: Double? private var currentTime : Double? 

显示链接用于更新currentTimepreviousTime

第三,要继续设置所有的东西,你需要重写下面的方法,我认为这是相当自我解释的:

 override func touchesBegan(touches: Set<NSObject>!, withEvent event: UIEvent!) { self.state = .Began displayLink.paused = false } override func touchesMoved(touches: Set<NSObject>!, withEvent event: UIEvent!) { if let view = self.view, touch = touches.first as? UITouch { self.state = .Changed let newLocation = touch.locationInView(view) self.previousTouchLocation = self.currentTouchLocation self.currentTouchLocation = newLocation } } override func touchesEnded(touches: Set<NSObject>!, withEvent event: UIEvent!) { self.state = .Ended displayLink.paused = true } override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) { self.state = .Cancelled displayLink.paused = true } 

第四,现在我们可以得到更有趣的一点 – 计算速度:

 func velocityInView(targetView: UIView) -> CGPoint { var velocity = CGPoint.zeroPoint if let view = self.view, prevTouchLocation = self.previousTouchLocation, currTouchLocation = self.currentTouchLocation, previousTime = self.previousTime, currentTime = self.currentTime { let targetPrevLocation = view.convertPoint(prevTouchLocation, toView: targetView) let targetCurrLocation = view.convertPoint(currTouchLocation, toView: targetView) let deltaTime = CGFloat(currentTime - previousTime) let velocityX = (targetCurrLocation.x - targetPrevLocation.x) / deltaTime let velocityY = (targetCurrLocation.y - targetPrevLocation.y) / deltaTime velocity = CGPoint(x: velocityX, y: velocityY) } return velocity } 

速度的计算使用公式:

 velocity = deltaDistance / deltaTime 

在这种情况下,取速度(x和y)的每个分量,并使用该方程计算每个轴的速度。 如果你想结合速度的两个组成部分,你会使用毕达哥拉斯定理:

 let distance = hypot(targetCurrLocation.x - targetPrevLocation.x, targetCurrLocation.y - targetPrevLocation.y) let velocity = distance / deltaTime 

第五,在你的视图控制器,你现在可以添加你的手势识别器,并使用action来获得拖动时的速度:

 override func viewDidLoad() { super.viewDidLoad() let recogniser = VelocityGestureRecogniser(target: self, action: Selector("movedGesture:")) self.view.addGestureRecognizer(recogniser) } func movedGesture(recogniser: VelocityGestureRecogniser) { let v = recogniser.velocityInView(self.view) println("velocity = \(v)") }