Search code examples
iosswiftuiswipegesturerecognizerswipe-gesture

Call function when SwipeGestureRecognizer swipe speed passes threshold


I'm currently programming an app, which contains a UIView with a UISwipeGestureRecognizer

I want the recognizer to recognize how fast the user is dragging in the recognizer's direction. When the speed is high enough (past a specific threshold) a custom action should occur. It's basically the same as in this post, but I need it written in Swift.

How do I translate that to Swift or is there a better way to do it?

Current Code, Xcode Errors marked as comments.

Touches began:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {


        //avoid multi-touch gesture
        if(touches.count > 1){
            return;
        }

        if let touch:UITouch = touches.first as? UITouch{
            let locator:CGPoint = touch.locationInView(self.view!)
            start = locator
            startTime = touch.timestamp
        }

Touches ended:

    override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {

    if let touch:UITouch = touches.first as? UITouch{
        let locator:CGPoint = touch.locationInView(self.view!)

        var dx:CGFloat = (locator.x - start!.x);
        var dy:CGFloat = (locator.y - start!.y);
        var magnitude:CGFloat = sqrt(dx*dx+dy*dy)

        if (magnitude >= kMinDistance) {
            // Determine time difference from start of the gesture
            var dt:CGFloat = CGFloat(touch.timestamp - startTime!)
            if (dt > kMinDuration) {
                // Determine gesture speed in points/sec
                var speed:CGFloat = magnitude / dt;
                 if (speed >= kMinSpeed && speed <= kMaxSpeed) {
                    // Swipe detected
                    swipedView()
    }}}}}

Solution

  • var start:CGPoint?
    var startTime:NSTimeInterval?
    
    var kMinDistance:CGFloat   = 25.0
    var kMinDuration:CGFloat   = 0.1
    var kMinSpeed:CGFloat      = 100.0
    var kMaxSpeed:CGFloat      = 500.0
    
    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
        //avoid multi-touch gesture
        if(touches.count > 1){
            return;
        }
    
        if let touch:UITouch = touches.first as? UITouch{
            let location:CGPoint = touch.locationInView(self.view!)
            start = location
            startTime = touch.timestamp
        }
    }
    
    override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
        if let touch:UITouch = touches.first as? UITouch{
            let location:CGPoint = touch.locationInView(self.view!)
    
            var dx:CGFloat = location.x - start!.x;
            var dy:CGFloat = location.y - start!.y;
            var magnitude:CGFloat = sqrt(dx*dx+dy*dy)
    
            if (magnitude >= kMinDistance) {
                // Determine time difference from start of the gesture
                var dt:CGFloat = CGFloat(touch.timestamp - startTime!)
                if (dt > kMinDuration) {
                    // Determine gesture speed in points/sec
                    var speed:CGFloat = magnitude / dt;
                    if (speed >= kMinSpeed && speed <= kMaxSpeed) {
                        // Swipe detected
                    }
                }
            }
        }
    }
    

    Honesty need to say that his has not been tested but I needed some code like this so this was converted on the go.

    EDIT: Tested and seems to work with Swift 1.2
    Please read the comments underneath your question and read How to Ask for your next question. You where lucky this time that I needed this code :)