How do I implement velocityInView: for a custom gesture recognizer?

痴心易碎 提交于 2020-01-02 12:16:07

问题


I am implementing a custom UIGestureRecognizer subclass.

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?


回答1:


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.

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?

The display link is for updating the currentTime and 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

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

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)")
}


来源:https://stackoverflow.com/questions/28552408/how-do-i-implement-velocityinview-for-a-custom-gesture-recognizer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!