ios - How to get a MKAnnotationView that's draggable without any delay? -
the below code works , gives me draggable annotation view. however, i've noticed annotation view not draggable beginning on, rather after finger has rested short moment on annotation view. when directly going drag movement dragging doesn't affect annotation view instead pans map. doesn't feel drag'n'drop. both on device , in simulator.
viewcontroller (delegate of mapview)
override func viewdidload() { /// ... let gesturerecognizer = uilongpressgesturerecognizer(target: self, action: #selector(addpin)) mapview.addgesturerecognizer(gesturerecognizer) } func addpin(gesturerecognizer: uigesturerecognizer) { if gesturerecognizer.state != uigesturerecognizerstate.began { return } annotation in mapview.annotations { mapview.removeannotation(annotation) } let touchlocationinview = gesturerecognizer.locationinview(mapview) let coordinate = mapview.convertpoint(touchlocationinview, tocoordinatefromview: mapview) let annotation = dragannotation(coordinate: coordinate, title: "draggable", subtitle: "") mapview.addannotation(annotation) } func mapview(mapview: mkmapview, viewforannotation annotation: mkannotation) -> mkannotationview? { if annotation.iskindofclass(dragannotation) { let reuseidentifier = "dragannotationidentifier" var annotationview: mkannotationview! if let dequeued = mapview.dequeuereusableannotationviewwithidentifier(reuseidentifier) { annotationview = dequeued } else { annotationview = mkannotationview(annotation: annotation, reuseidentifier: reuseidentifier) } annotationview.annotation = annotation annotationview.image = uiimage(named: "bluedisk2") annotationview.canshowcallout = false annotationview.draggable = true return annotationview } return nil } func mapview(mapview: mkmapview, annotationview view: mkannotationview, didchangedragstate newstate: mkannotationviewdragstate, fromoldstate oldstate: mkannotationviewdragstate) { switch (newstate) { case .starting: view.dragstate = .dragging case .ending, .canceling: view.dragstate = .none default: break } }
dragannotation
import uikit import mapkit class dragannotation : nsobject, mkannotation { var coordinate: cllocationcoordinate2d { didset { print(coordinate) } } var title: string? var subtitle: string? init(coordinate: cllocationcoordinate2d, title: string, subtitle: string) { self.coordinate = coordinate self.title = title self.subtitle = subtitle } }
i don't think can change draggable delay, disable , add own drag gesture has no delay (or shorter delay):
func mapview(mapview: mkmapview, viewforannotation annotation: mkannotation) -> mkannotationview? { if annotation mkuserlocation { return nil } var view = mapview.dequeuereusableannotationviewwithidentifier("foo") if view == nil { view = mkpinannotationview(annotation: annotation, reuseidentifier: "foo") view?.draggable = false let drag = uilongpressgesturerecognizer(target: self, action: #selector(handledrag(_:))) drag.minimumpressduration = 0 // set whatever want drag.allowablemovement = .max view?.addgesturerecognizer(drag) } else { view?.annotation = annotation } return view } private var startlocation = cgpointzero func handledrag(gesture: uilongpressgesturerecognizer) { let location = gesture.locationinview(mapview) if gesture.state == .began { startlocation = location } else if gesture.state == .changed { gesture.view?.transform = cgaffinetransformmaketranslation(location.x - startlocation.x, location.y - startlocation.y) } else if gesture.state == .ended || gesture.state == .cancelled { let annotationview = gesture.view as! mkannotationview let annotation = annotationview.annotation as! dragannotation let translate = cgpoint(x: location.x - startlocation.x, y: location.y - startlocation.y) let originallocation = mapview.convertcoordinate(annotation.coordinate, topointtoview: mapview) let updatedlocation = cgpoint(x: originallocation.x + translate.x, y: originallocation.y + translate.y) annotationview.transform = cgaffinetransformidentity annotation.coordinate = mapview.convertpoint(updatedlocation, tocoordinatefromview: mapview) } }
by way, if you're going change coordinate
of annotation, want add dynamic
keyword custom class coordinate
declaration appropriate kvo notifications issued.
class dragannotation: nsobject, mkannotation { dynamic var coordinate: cllocationcoordinate2d var title: string? var subtitle: string? init(coordinate: cllocationcoordinate2d, title: string? = nil, subtitle: string? = nil) { self.coordinate = coordinate self.title = title self.subtitle = subtitle super.init() } }
note, in example, set delay zero. means if tap on annotation (the typical ui "show callout"), may prevent working correctly. treat short drag. why standard ui requires delay in long press before dragging.
so, reason, hesitate override behavior shown above because different standard map behavior end user familiar with. if map behaves differently other maps on user's device, source of frustration.
Comments
Post a Comment