Bob
Bob

Reputation: 188

Conflict between Pan Gesture and Tap Gestures

I'm currently working on a game that uses UIGestureRecognizers. I'm using the pan gesture to move the player around and the tap gesture to detect other UI button touches. Everything seems to work fine except that there is a conflict between the 2 gestures. Whenever the player is on the move (pan gesture gets recognized) the game ignores all my tap gestures (Once the pan gesture is recognized, the view won't recognize tap gestures). Can someone please show me how to make the 2 gestures work together. I want the player to stop moving when a UI button gets tapped. In another word, I want to cancel the pan gesture whenever a tap gesture is recognized.

Thank you so much in advance!

Here is how I setup the 2 gestures:

   let singleTap = UITapGestureRecognizer(target: self, action: #selector(doSingleTap))
    singleTap.numberOfTapsRequired = 1
    singleTap.delegate = self
    self.view?.addGestureRecognizer(singleTap)


   let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan))
    panGesture.minimumNumberOfTouches = 1
    panGesture.delegate = self
    self.view?.addGestureRecognizer(panGesture)


@objc func handlePan(gestureReconizer: UIPanGestureRecognizer) {

    if isPaused || player.isInAction {return}

    let translation = gestureReconizer.translation(in: self.view)

    if gestureReconizer.state == .changed {
        let angle = 180 + (atan2(-translation.x, translation.y) * (180/3.14159))
        player.movementAngle = angle
        player.atState = .Walk
    }
    if gestureReconizer.state == .ended {
        player.movementAngle = 0.0
        if player.atState == .Walk {
            player.atState = .Idle
        }
    }
}



@objc func doSingleTap(gestureReconizer: UITapGestureRecognizer) {

    let originaTapLocation = gestureReconizer.location(in: self.view)

    let location = convertPoint(fromView: originaTapLocation)
    let node = atPoint(location)

        switch node.name {
        case "HeroAvatar":
            //do stuff here
            break

        case "Fire":

            //do stuff here
            break

        case "Potion":
            //do stuff here
            break

        default:
            break
        } 
}

Upvotes: 0

Views: 3845

Answers (1)

iVarun
iVarun

Reputation: 6631

You need to implement delegate method of UIGestureRecognizerDelegate like below:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
                       shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {

    // Don't recognize a single tap gesture until a pan gesture fails.
    if gestureRecognizer == singleTap &&
        otherGestureRecognizer == panGesture {
        return true
    }
    return false
}

Hope this will work for you :)

For more info Apple Doc Preferring One Gesture Over Another

Upvotes: 4

Related Questions