Xcoder
Xcoder

Reputation: 1453

UISwipeGestureRecognizer doesn't work on presented VC and view

The hierarchy:

In the initializer for GameView, I have this code to configure the swipe gestures:

let leftGesture = UISwipeGestureRecognizer(target: self, action: #selector(leftSwipe))
leftGesture.direction = .left
self.addGestureRecognizer(leftGesture)

let rightGesture = UISwipeGestureRecognizer(target: self, action: #selector(rightSwipe))
rightGesture.direction = .right
self.addGestureRecognizer(rightGesture)

let downGesture = UISwipeGestureRecognizer(target: self, action: #selector(downSwipe))
downGesture.direction = .down
self.addGestureRecognizer(downGesture)

Corresponding selectors:

@objc func downSwipe() {
    //code
}

@objc func leftSwipe() {
    //code
}

@objc func rightSwipe() {
    //code
}

The selectors are not getting called. However, when I make GameVC the initial VC that is being displayed(by dragging the storyboard arrow onto GameVC), the gestures work as intended. This makes me think that calling present() might've messed up the hierarchy that gestures operate on, but I'm not quite sure.

Upvotes: 1

Views: 816

Answers (1)

Asperi
Asperi

Reputation: 257729

You have to indicate in that your gestures can be handled simultanaously by providing corresponding delegate method.

The below demo code works using above. Tested with Xcode 11.4 / iOS 13.4

class GameView: UIView {
}

// in Storyboard just empty view of above custom GameView
class GameVC: UIViewController, UIGestureRecognizerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let leftGesture = UISwipeGestureRecognizer(target: self, action: #selector(leftSwipe))
        leftGesture.direction = .left
        leftGesture.delegate = self
        self.view.addGestureRecognizer(leftGesture)

        let rightGesture = UISwipeGestureRecognizer(target: self, action: #selector(rightSwipe))
        rightGesture.direction = .right
        rightGesture.delegate = self
        self.view.addGestureRecognizer(rightGesture)

        let downGesture = UISwipeGestureRecognizer(target: self, action: #selector(downSwipe))
        downGesture.direction = .down
        downGesture.delegate = self
        self.view.addGestureRecognizer(downGesture)

    }

    // allows own view gestures to run with system originated simultaneously
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        true
    }

    @objc func downSwipe() {
        print(">> down swipe")
    }

    @objc func leftSwipe() {
        print(">> left swipe")
    }

    @objc func rightSwipe() {
        print(">> right swipe")
    }
}

// Initial VC, in storyboard contains only button linked to below showGame action
class ViewController: UIViewController {

    @IBAction func showGame(_ sender: Any) {
        let vc = self.storyboard?.instantiateViewController(withIdentifier: "GameVC") as! GameVC
        self.present(vc, animated: true, completion: nil)
    }
}

Upvotes: 1

Related Questions