如何为自定义手势识别器实现 velocityInView: ? [英] How do I implement velocityInView: for a custom gesture recognizer?
问题描述
我正在实现一个自定义的 UIGestureRecognizer
子类.
I am implementing a custom UIGestureRecognizer
subclass.
我想以与 UIPanGestureRecognizer
相同的方式实现 velocityInView:
.但我不知道如何去做.如何以点/秒为单位计算速度?
I would like to implement velocityInView:
the same way that UIPanGestureRecognizer
has done it. But I'm not sure how to go about doing it. How do I calculate the velocity in points / second?
推荐答案
首先,如果你使用 Swift,你将需要创建一个桥接头和 #import<UIKit/UIGestureRecognizerSubclass.h>
以便您可以覆盖 UIGestureRegoniser
的触摸开始/移动/取消/结束方法.如果您使用的是 Objective-C,只需将该 import
语句放在 .h 或 .m 文件中.
Firstly, if you're using Swift, you're going to need to create a Bridging Header and #import <UIKit/UIGestureRecognizerSubclass.h>
so you can override UIGestureRegoniser
's touches began/moved/cancelled/ended methods. If you're using Objective-C just put that import
statement in the .h or .m file.
其次,一旦您创建了 UIGestureRecognizer
子类,您就需要在其中添加以下变量:
Secondly, once you've created your UIGestureRecognizer
subclass you need these variables in it:
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?
显示链接用于更新currentTime
和previousTime
.
第三,要继续设置您需要覆盖以下方法的所有内容,我认为这完全不言自明:
Thirdly, to continue setting everything up you need to override the following methods, I think it's all fairly self-explanatory:
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
}
第四,现在我们可以进入更有趣的部分 - 计算速度:
Fourthly, now we can get to the more interesting bit - calculating the velocity:
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
}
使用以下公式计算速度:
The velocity is calculated using the equation:
velocity = deltaDistance / deltaTime
在本例中,获取速度的每个分量(x 和 y)并使用该方程计算每个轴的速度.如果您想组合速度的两个分量,您可以像这样使用毕达哥拉斯定理:
In this case, take each component of the velocity (x and y) and use that equation to calculate the velocity in each axis. If you wanted to combine both components of the velocity you would use Pythagoras' Theorem like so:
let distance = hypot(targetCurrLocation.x - targetPrevLocation.x,
targetCurrLocation.y - targetPrevLocation.y)
let velocity = distance / deltaTime
第五,在您的视图控制器中,您现在可以添加手势识别器并使用 action
来获取在屏幕上拖动时的速度:
Fifthly, in your view controller you can now add your gesture recognizer and use action
to get the velocity when dragging over the screen:
override func viewDidLoad() {
super.viewDidLoad()
let recognizer = VelocityGestureRecognizer(target: self, action: Selector("movedGesture:"))
self.view.addGestureRecognizer(recognizer)
}
func movedGesture(recognizer: VelocityGestureRecognizer) {
let v = recognizer.velocityInView(self.view)
println("velocity = \(v)")
}
这篇关于如何为自定义手势识别器实现 velocityInView: ?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!