Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling Multiple GestureRecognizers

I've run into an issue understanding UIGestureRecognizers. My goal right now is to have a set of GestureRecognizers to do different tasks, for example:

override func viewDidLoad() {
    mainScene = GameScene(size: self.view.bounds.size)
    main = view as! SKView

    mainScene.panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(shiftView(recognizer:)))
    main.addGestureRecognizer(mainScene.panRecognizer)

    mainScene.tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(testTap(recognizer:)))
    main.addGestureRecognizer(mainScene.tapRecognizer)

    mainScene.pinchRecognizer = UIPinchGestureRecognizer(target: self, action: #selector(zoomView(recognizer:)))
    main.addGestureRecognizer(mainScene.pinchRecognizer)

This is my game View Controller where I handle actions such as panning around a map, zooming, and tapping on map tiles. But I also want to be able to move sprites with a UITapGestureRecognizer so I also created this in my GameScene:

if startGame == true{
            self.startGame()
            for node in (self.tempGameBoard.landShipLayer.children as? Array<landship>)! {

                node.landShipInteraction = UITapGestureRecognizer(target: self, action: #selector(handleTap(recognizer:)))
                parentViewController.view.addGestureRecognizer(node.landShipInteraction)
            }
        }

The landShip in this case is representative of a sprite on screen that I would like to interact with via gesture recognizers.

My issue is that if I add this second set of recognizers, the tapping action becomes completely unresponsive. I can still zoom and pan, but the tapping behaviors I expect on my map tiles do not occur. I feel as though I am missing some understanding of how the gesture recognizers work.

Any ideas?

Thanks!

like image 822
Aleksandr Avatar asked Jan 29 '17 06:01

Aleksandr


1 Answers

The UIGestureRecognizerDelegate has a special function managing simultaneous recognition of several gestures on the same object, that will do the trick.

1) Set your UIViewController to conform UIGestureRecognizerDelegate

2) Implement the following function:

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

    if (gestureRecognizer == mainScene.panRecognizer || gestureRecognizer == mainScene.pinchRecognizer) && otherGestureRecognizer == mainScene.tapRecognizer {
        return true
    }
    return false
}

In this particular example we allow the tap gesture to get triggered simultaneously with panning and pinching.

3) Then just assign the delegates to the pan and pinch gesture recognizers:

override func viewDidLoad() {
    // your code...

    // Set gesture recognizers delegates
    mainScene.panRecognizer.delegate = self
    mainScene.pinchRecognizer.delegate = self
}
like image 145
Vadim Popov Avatar answered Oct 17 '22 17:10

Vadim Popov