Shane O'Seasnain
Shane O'Seasnain

Reputation: 3674

touchesEnded not being recognised

when I call touchesBegan() with

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        print("TOUCH_BEGAN")
}

I get the print statement. I've noticed though that if I don't move the point of contact,

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

        print("TOUCH_ENDED")
}

isn't being called but is when I move the point of contact. Is there some minimum movement needed to call touchesEnded()? If so, is there a way of overriding this, to ensure touchesEnded() is always called?


The full code is too long to add but a bit more below:

import SpriteKit
import UIKit
import Foundation

class GameScene: SKScene, SKPhysicsContactDelegate {
    // MARK: Properties
    var touchStart: CGPoint?
    let minSwipeDistance:CGFloat = 22
    var distance: CGFloat = 0

    override func didMoveToView(view: SKView) {
        super.didMoveToView(view)
        //...

        // MARK: INCLUDE SWIPE GESTURES

        let swipeRight: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedRight:"))
        swipeRight.direction = .Right
        swipeRight.cancelsTouchesInView = false
        swipeRight.delaysTouchesEnded = false
        view.addGestureRecognizer(swipeRight)

        let swipeLeft: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedLeft:"))
        swipeLeft.direction = .Left
        swipeLeft.cancelsTouchesInView = false
        swipeLeft.delaysTouchesEnded = false
        view.addGestureRecognizer(swipeLeft)

        let swipeUp: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedUp:"))
        swipeUp.direction = .Up
        swipeUp.cancelsTouchesInView = false
        swipeUp.delaysTouchesEnded = false
        view.addGestureRecognizer(swipeUp)

        let swipeDown: UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedDown:"))
        swipeDown.direction = .Down
        swipeDown.cancelsTouchesInView = false
        swipeDown.delaysTouchesEnded = false
        view.addGestureRecognizer(swipeDown)
    }

    // MARK: ******* User Interaction ******

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if let touch = touches.first {
            touchStart = touch.locationInNode(self)
            let location = touch.locationInNode(self)
            let node = nodeAtPoint(location)
        }
    }

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    }

    override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {    
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if let touch = touches.first, start = touchStart {
            let location = touch.locationInNode(self)
            // Compute the distance between the two touches
            let dx = location.x - start.x
            let dy = location.y - start.y
            distance = sqrt(dx*dx + dy*dy)
            if distance < minSwipeDistance {
                let node = nodeAtPoint(location)
                print("NODE NAME: \(node.name)")
            }
        }
        // Reset the initial location
        touchStart = nil
    }

    // MARK: handle swipes
    func swipedRight(sender: UISwipeGestureRecognizer) {
        print("swiped right")
    }

    func swipedLeft(sender: UISwipeGestureRecognizer) {
        print("swiped left")
    }

    func swipedUp(sender: UISwipeGestureRecognizer) {
        print("swiped up")
    }

    func swipedDown(sender: UISwipeGestureRecognizer) {
        print("swiped down")
    }
}

Upvotes: 6

Views: 5366

Answers (1)

matt
matt

Reputation: 535566

You cannot ensure touchesEnded is called, because touchesCancelled might be called instead. You should always implement ending functionality in both.

Upvotes: 13

Related Questions