Gesture recognizer with delaysTouchesBegan stops all calls to touchesMoved?

1.7k Views Asked by At

The view controller code below demonstrates my question. It prints some debugging statements in response to touch events and a pinch gesture.

If the gesture recognizer is disabled, and I drag a finger on the screen, everything works as I expected: the controller gets a touchesBegan, a bunch of touchesMoved, and a touchesEnded. But if I enable the gesture recognizer and set its delaysTouchesBegan property to true, and drag a single finger, the controller receives only touchesBegan and touchesEnded calls - no touchesMoved.

The docs for delaysTouchesBegan suggest that touch events will pile up and be delivered after the gesture recognizer fails. Is this the expected behavior - to lose all the touchesMoved events?

class ViewController: UIViewController {

    var gr: UIPinchGestureRecognizer!

    override func viewDidLoad() {
        super.viewDidLoad()
        gr = UIPinchGestureRecognizer(target: self, action: #selector(pinched(_:)))
        gr.delaysTouchesBegan = true
        view.addGestureRecognizer(gr)
    }

    @IBAction func buttonTapped(_ sender: Any) {
        gr.isEnabled = !gr.isEnabled
        print("pinch recognizer enabled: \(gr.isEnabled)")
    }

    @objc func pinched(_ gr: Any?) {
        print("pinched")
    }

    var i = 0

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        i = 0
        print("touchesBegan")
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touchesMoved \(i)")
        i += 1
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touchesEnded")
    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("touchesCancelled")
    }
}
1

There are 1 best solutions below

3
Caleb Wells On

A pinch gesture recognizer reports changes each time the distance between the fingers change. The distance between the fingers is reported as a scale factor. So you will want to look at the scale factor, not touchesMoved. Was that helpful?

@objc func pinched(_ gr: UIPinchGestureRecognizer) {

    if gr.state == .began  {
        print("began")
    }

    if gr.state == .changed {
        print("scale: \(gr.scale)")
    }

    if gr.state == .ended {
        print("ended")
    }
}

Handling Pinch Gestures

Handling Pinch Gestures ( Swift 4 - 2018 )