iOS Swift MapKit making an annotation draggable by the user?

How do I make it possible, using MapKit in Swift, for the user to drag an annotation from one position to another within the map? I have set the annotation view to be draggable, when my map view delegate creates the annotation view, like this:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    var v : MKAnnotationView! = nil
    if annotation is MyAnnotation {
        let ident = "bike"
        v = mapView.dequeueReusableAnnotationView(withIdentifier:ident)
        if v == nil {
            v = MyAnnotationView(annotation:annotation, reuseIdentifier:ident)
        }
        v.annotation = annotation
        v.isDraggable = true
    }
    return v
}

The result is that the user can sort of drag the annotation – but only once. After that, the annotation becomes impossible to drag, and even worse, the annotation now no longer “belongs” to map – when the map is scrolled / panned, the annotation holds still rather than scrolling / panning with the map. What am I doing wrong?

  • How to deal with a user input string that gives an “unprintable ascii character found in source file” error when pasted into Xcode?
  • How could I create a shortcut on desktop in iOS through an app
  • SpriteKit SKPhysicsBody broken collisions
  • Presenting a modal controller without knowing the current view controller?
  • AES gets different results in iOS (Obj-C) and Android (Java)
  • IBOutlet does not display its value in UI
  • Solutions Collect From Internet About “iOS Swift MapKit making an annotation draggable by the user?”

    It isn’t enough to mark the annotation view by setting isDraggable to true. You must also implement mapView(_:annotationView:didChange:fromOldState:) in your map view delegate – and (even more important) this implementation must not be empty! Rather, your implementation must, at a minimum, communicate the drag state from the incoming parameters to the annotation view, like this:

    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationViewDragState, fromOldState oldState: MKAnnotationViewDragState) {
        switch newState {
        case .starting:
            view.dragState = .dragging
        case .ending, .canceling:
            view.dragState = .none
        default: break
        }
    }
    

    Once you do that, the annotation will be properly draggable by the user.

    (Many thanks to this answer for explaining this so clearly. I can’t claim any credit! My answer here is merely a translation of that code into Swift.)