H.N. H.N. - 24 days ago 12
Swift Question

Stop Updating Location when I drag the mapview

I have a mapview which his updating location. So if I am moving my loocating keeps updating.
I want it to stop if I drag the map and try to see another thing on it.
How can I do this?

I tried this solution, to detect when map is dragged:
Determine if MKMapView was dragged/moved in Swift 2.0

I am working in swift3.

1: Add the gesture recognizer in viewDidLoad:

let mapDragRecognizer = UIPanGestureRecognizer(target: self, action: Selector(("didDragMap:")))
mapDragRecognizer.delegate = self
self.map.addGestureRecognizer(mapDragRecognizer)


2: Add the protocol UIGestureRecognizerDelegate to the view controller so it works as delegate.

class MapViewController: UIViewController, UIGestureRecognizerDelegate



  1. Added this other code:

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

    func didDragMap(gestureRecognizer: UIGestureRecognizer) {
    if (gestureRecognizer.state == UIGestureRecognizerState.began) {
    print("Map drag began")
    self.locationManager.stopUpdatingLocation()
    }

    if (gestureRecognizer.state == UIGestureRecognizerState.ended) {
    print("Map drag ended")
    }
    }



The app crashes if I drag map. And I got this:
"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[app.ViewController didDragMap:]: unrecognized selector sent to instance 0x7fdf1fd132c0'" (..) "libc++abi.dylib: terminating with uncaught exception of type NSException"

Answer

Selector syntax has changed in Swift 3. Your gesture recognizer should now look like this:

let mapDragRecognizer = UIPanGestureRecognizer(target: self, action: #selector(didDragMap))

func didDragMap(_ gestureRecognizer: UIGestureRecognizer) {
   if (gestureRecognizer.state == UIGestureRecognizerState.began) {
       print("Map drag began")
       self.locationManager.stopUpdatingLocation()
   }
   if (gestureRecognizer.state == UIGestureRecognizerState.ended) {
       print("Map drag ended")
   }
}

Note that didDragMap(_:) is declared according to the new Swift API Design Guidelines

I would also replace your if statements with a switch statement as the compiler is able to optimize it better once there are more than two cases, and it is more clear. i.e.

func didDragMap(_ gestureRecognizer: UIGestureRecognizer) {
    switch gestureRecognizer.state {
    case .began:
        print("Map drag began")
        self.locationManager.stopUpdatingLocation()

    case .ended:
        print("Map drag ended")

    default:
        break
    }
}
Comments