Search code examples
iosswiftmkannotationmkannotationview

How undo a MapKit annotation drag


If, in mapView didChangeDragState, I detect the annotation has been dragged to an unwanted location, I can cancel the drag in mapView:didChangeDragState.

 case .Dragging:  
            let inColorado = StateOutline.inColorado(view.annotation!.coordinate)
            if !inColorado {
                view.dragState = .Canceling
            }

Unfortunately, that leaves the pin at the position in the unwanted location where the drag was cancelled.

One would like to set the annotation to

  • a valid coordinate
  • or restore to the pre-drag coordinate
  • or set to the last valid location of the drag

    case .Canceling:
            view.annotation!.coordinate = StateOutline.coloradoCenter()
            view.dragState = .None
        }
    

That coordinate setting is not permitted because view.annotation!.coordinate is a get-only property.

How might one undo the annotation drag?

Using MKAnnotation setCoordinate isn’t something to consider — it was removed in iOS 8.3.

The only thing that comes to mind is to replace that annotation with a new one and set the coordinate on that. Ideally the pin coordinate would be set to its last valid location.


Solution

  • Your mistake here is believing that an annotation's coordinate cannot be set. It can. The MKAnnotation protocol does not dictate a settable coordinate, but all actual adopters have one. Just use an MKPointAnnotation. Its coordinate is settable. You may even be using one already!

    public class MKPointAnnotation : MKShape {
        public var coordinate: CLLocationCoordinate2D
    }
    

    You can even write your own MKAnnotation adopter:

    import UIKit
    import MapKit
    
    class MyAnnotation : NSObject, MKAnnotation {
        dynamic var coordinate : CLLocationCoordinate2D
        var title: String?
        var subtitle: String?
    
        init(location coord:CLLocationCoordinate2D) {
            self.coordinate = coord
            super.init()
        }
    }