0

I am making an app where you can add pins to map locations via a long press. However, the long press appears to be duplicating the locations. Here is my code:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

let userLocation = locations[0]

if activePlace == -1 {

    latitude = userLocation.coordinate.latitude

    longitude = userLocation.coordinate.longitude

} else {

    latitude = Double(latitudePassed)!

    longitude = Double(longitudePassed)!

}



let latDelta : CLLocationDegrees = 0.05

let lonDelta : CLLocationDegrees = 0.05

let span = MKCoordinateSpan(latitudeDelta: latDelta, longitudeDelta: lonDelta)

let location = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)

let region = MKCoordinateRegion(center: location, span: span)

map.setRegion(region, animated: true)

let uilpgr = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.longpress(gestureRecognizer:)) )

uilpgr.minimumPressDuration = 2

map.addGestureRecognizer(uilpgr)


}

@objc func longpress(gestureRecognizer: UIGestureRecognizer) {

let touchpoint = gestureRecognizer.location(in: self.map)

print(touchpoint)

let coordinate = map.convert(touchpoint, toCoordinateFrom: self.map)

let annotation = MKPointAnnotation()

annotation.coordinate = coordinate

annotation.title = "New Place"

let annotationLat = coordinate.latitude

let annotationLon = coordinate.longitude

places.append(["name": annotation.title!, "latitude": String(annotationLat), "longitude": String(annotationLon)])

map.addAnnotation(annotation)

}

As you can see, I'm printing the touchpoint at the beginning of the function and I'm getting the same location printing several times - sometimes twice, sometimes up to 12 times. I've trawled StackOverflow and cannot find a similar issue... any help would be greatly appreciated.

DevB1
  • 1,235
  • 3
  • 17
  • 43

1 Answers1

0

Long-press gestures are continuous.

Try with the .began state, something like this:

@objc func longpress(gestureRecognizer: UIGestureRecognizer) {

    if gestureRecognizer.state == .began {

        let touchpoint = gestureRecognizer.location(in: self.map)

        print(touchpoint)

        let coordinate = map.convert(touchpoint, toCoordinateFrom: self.map)

        let annotation = MKPointAnnotation()

        annotation.coordinate = coordinate

        annotation.title = "New Place"

        let annotationLat = coordinate.latitude

        let annotationLon = coordinate.longitude

        places.append(["name": annotation.title!, "latitude": String(annotationLat), "longitude": String(annotationLon)])

        map.addAnnotation(annotation)
    }
}

Also try to trigger addGestureRecognizer only once, maybe in viewDidLoad where you setup/initiate map, so this should be just in viewDidLoad for example and fired once your map has been initialized:

let uilpgr = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.longpress(gestureRecognizer:)) )
uilpgr.minimumPressDuration = 2
map.addGestureRecognizer(uilpgr)

To know more about UIGestureRecognizer States follow Apple's documentation: https://developer.apple.com/documentation/uikit/uigesturerecognizer/state

denis_lor
  • 6,212
  • 4
  • 31
  • 55
  • Thanks @denis_lor. This works great in terms of printing the location just the once. However, it does mean that the pin only appears once the user stops the long press... which is not ideal because they have no way of knowing if they have pressed for long enough ... – DevB1 Aug 08 '19 at 07:51
  • 1
    oh, I just tried using the .began state and that worked great !! I think this will be fine. Thanks so much for your help. – DevB1 Aug 08 '19 at 07:54
  • I didn't know your intentions :) Let me update my answer! – denis_lor Aug 08 '19 at 07:55
  • @DaveB1 exactly! That will do it, I updated my answer right away I read your intentions in the comment :) Glad it helped out! – denis_lor Aug 08 '19 at 07:56