0

I have a gesture to add a pin on the map plus when I add that pin I do geocode to get that pin address. The problem is that everytime I touch the map to add a pin it call my gesture function twice for no reason

The print("city:", placemark.locality ?? "") line is called twice every time I touch the map

class PlaceYourPinpointViewController: UIViewController, UIGestureRecognizerDelegate {

    // MARK: - Variables

    @IBOutlet weak var mapView: MKMapView!
    @IBOutlet weak var nextBarButton: UIBarButtonItem!
    @IBOutlet weak var textView: UITextView!
    let annotation = MKPointAnnotation()

    var newLocation = CLLocation()
    let geocoder = CLGeocoder()
    var placemark: CLPlacemark?

    var addAnnotationGesture = UILongPressGestureRecognizer()
    var panGesture = UIPanGestureRecognizer()

    // MARK: - IOS Basic

    override func viewDidLoad() {
        super.viewDidLoad()
        addPinGesture()
        didDragMap()
        removePinGesture()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        setLaunchZoom()
    }

    // MARK: - Actions

    @IBAction func cancel() {
        dismiss(animated: true, completion: nil)
    }

    @objc func addPin(gestureRecognizer: UIGestureRecognizer) {
        let touchPoint = gestureRecognizer.location(in: mapView)
        let newCoordinates = mapView.convert(touchPoint, toCoordinateFrom: mapView)

        annotation.coordinate = newCoordinates
        self.mapView.addAnnotation(annotation)

        geocode(latitude: annotation.coordinate.latitude, longitude: annotation.coordinate.longitude) { placemark, error in
            guard let placemark = placemark, error == nil else { return }
            // you should always update your UI in the main thread
                print("city:", placemark.locality ?? "")
                self.textView.text = self.string(from: placemark)
        }
        nextBarButton.isEnabled = true
    }

    @objc func removePin(gestureRecognizer: UIGestureRecognizer) {
        self.mapView.removeAnnotation(annotation)
    }

    // MARK: - Private Methods

    func addPinGesture() {
        addAnnotationGesture = UILongPressGestureRecognizer(target: self, action: #selector(addPin))
        addAnnotationGesture.minimumPressDuration = 0.06
        mapView.addGestureRecognizer(addAnnotationGesture)
    }

    func removePinGesture() {
        let removeAnnotationGesture = UITapGestureRecognizer(target: self, action: #selector(removePin))
        removeAnnotationGesture.numberOfTapsRequired = 1
        self.mapView.addGestureRecognizer(removeAnnotationGesture)
    }

    func didDragMap() {
        panGesture = UIPanGestureRecognizer(target: self, action: nil)
        panGesture.delegate = self
        mapView.addGestureRecognizer(panGesture)
    }

    func setLaunchZoom() {
        let region = MKCoordinateRegion(center: mapView.userLocation.coordinate, latitudinalMeters: 600, longitudinalMeters: 600)
        mapView.setRegion(mapView.regionThatFits(region), animated: true)
    }

    func string(from placemark: CLPlacemark) -> String {
        // make address label

        var line = ""
        line.add(text: placemark.subThoroughfare)
        line.add(text: placemark.thoroughfare, separatedBy: " ")
        line.add(text: placemark.locality, separatedBy: ", ")
        line.add(text: placemark.country, separatedBy: ", ")
        line.add(text: placemark.postalCode, separatedBy: ", ")
        return line
    }

    func geocode(latitude: CLLocationDegrees, longitude: CLLocationDegrees, completion: @escaping (CLPlacemark?, Error?) -> ())  {
        CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: latitude, longitude: longitude)) { placemarks, error in
            guard let placemark = placemarks?.first, error == nil else {
                completion(nil, error)
                return
            }
            completion(placemark, nil)
        }
    }

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        // Do not begin the long press unless the pan fails.
        if gestureRecognizer == self.panGesture && otherGestureRecognizer == self.addAnnotationGesture {
            return true
        }
        return false
    }
}
Ashley Mills
  • 50,474
  • 16
  • 129
  • 160
mathias merlot
  • 585
  • 1
  • 4
  • 4

1 Answers1

1

the gesture has states you have to call it either in begin or end

@objc func addPin(gestureRecognizer: UIGestureRecognizer) {   
   if gestureRecognizer.state != .began {
     return 
  }
}
Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87