ja12
ja12

Reputation: 360

UILongPressGestureRecognizer in IOS 13 second long press two times on MKMapView not work

I have set up a UILongPressGestureRecognizer that works fine in versions before IOS 13, but in this version to detect the second long press, I have to press twice.

That is to say:

1º LongPress -> Work Fine show "long tap"

2º LongPress -> Not work

3º LongPress -> Work Fine show "long tap"

4º LongPress -> Not work

...

This is my code.

    let longTapGesture = UILongPressGestureRecognizer(target: self, action: #selector(longTap))
    longTapGesture.delegate = self
    longTapGesture.numberOfTouchesRequired = 1
    longTapGesture.cancelsTouchesInView = false
    
    mapView.addGestureRecognizer(longTapGesture)

Function called is:

    @objc func longTap(sender: UIGestureRecognizer){
      print("long tap")
      .....
    }

Upvotes: 5

Views: 586

Answers (2)

Gabriel Medina
Gabriel Medina

Reputation: 91

In iOS 13, UILongPressGestureRecognizer only recognizes a single long press per touch. You could try to set "delaysTouchesBegan" to false.

Fox example:

let longTapGesture = UILongPressGestureRecognizer(target: self, action: #selector(longTap))
longTapGesture.delegate = self
longTapGesture.numberOfTouchesRequired = 1
longTapGesture.cancelsTouchesInView = false
longTapGesture.delaysTouchesBegan = false

mapView.addGestureRecognizer(longTapGesture)

Here is the resources I found: delaysTouchesBegan Doc

Upvotes: 0

HangarRash
HangarRash

Reputation: 14976

The solution to this is to allow for simultaneous gestures. Simply set the long press gesture's delegate and implement the following delegate method:

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

That's it. The long press gesture on the map view will now work every time.

As a demonstration, create a new iOS project based on Swift and storyboard. Replace the provided ViewController.swift implementation with the following:

import UIKit
import MapKit

class ViewController: UIViewController {
    let mapView = MKMapView()

    override func viewDidLoad() {
        super.viewDidLoad()

        mapView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(mapView)

        NSLayoutConstraint.activate([
            mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            mapView.topAnchor.constraint(equalTo: view.topAnchor),
            mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        ])

        let lp = UILongPressGestureRecognizer(target: self, action: #selector(longPress))
        lp.delegate = self
        view.addGestureRecognizer(lp)
    }

    @objc func longPress(_ gesture: UILongPressGestureRecognizer) {
        switch gesture.state {
            case .began:
                print("began")
            case .ended:
                print("ended")
            case .changed:
                print("changed")
            case .cancelled:
                print("cancelled")
            default:
                print("other")
        }
    }
}

extension ViewController: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
}

Do note that shouldRecognizeSimultaneouslyWith will get called quite a few times. There seems to be at least 3 other gestures, including another long press gesture that expects two touches. So it's probably best not to setup your own long press gesture to require two touches.

Upvotes: 3

Related Questions