0

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()
    }}}}}
Community
  • 1
  • 1
Sam0711er
  • 834
  • 10
  • 24
  • 1
    Try translating it and come back with a specific question about that if you have problems – Wain Apr 14 '15 at 19:22

1 Answers1

3
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 :)

Community
  • 1
  • 1
milo526
  • 5,012
  • 5
  • 41
  • 60
  • Thank you, Xcode says there isn't everything alright. My code now looks like I edited in the question – Sam0711er Apr 14 '15 at 21:17
  • Sorry both 'self' should be 'self.view!' – milo526 Apr 14 '15 at 21:23
  • Ok, that fixed Xcode's problems, but now, it isn't detecting the swipes. – Sam0711er Apr 14 '15 at 21:35
  • Trial and error with the values, did you put them inside a view Controller? – milo526 Apr 14 '15 at 21:42
  • Also try overriding the touch functions using `override` in front of both functions – milo526 Apr 14 '15 at 21:45
  • Yes, they are in a View Controller. In `touches ended` and `touches began` I also do have some other code. Would it be helpful, if I provided the rest of those functions? – Sam0711er Apr 14 '15 at 21:45
  • Ok, now it's getting a little bit strange. Now everytime, i tap the display shorter dann my minimumvalue, nothing happens, when I tap it longer, it does the action, but when I move my finger, like it should and then release it, again nothing happens. Do we have to include `touches moved`? – Sam0711er Apr 14 '15 at 21:52
  • Try lowering kMinSpeed to let' stay 25 and see if that does something – milo526 Apr 15 '15 at 07:27
  • Ok, now it works pretty much! I do have one more question. In my `touchesEnded` method, I have an event, that lets a card jump back to its origin. This mechanism does have a bug now. When I swipe up and reach my threshold, the action works as it should, but when I first swipe down, the card hangs. To explain it better, I've uploaded a short screen recording of the app. [link](https://www.youtube.com/watch?v=PmBwJ7_y7BE) It should work like Apple's Passbook. So, how do I fix this bug and how can I set, that the function gets called when I swipe up (not down) – Sam0711er Apr 15 '15 at 12:56
  • Please provide your (and mine) code and ask this in a new question. If you feel like my answer answered the question you asked in this question please mark it as such (using the green check mark). Asking your next question in a new question will result in better help for others with the same problem. – milo526 Apr 15 '15 at 14:32