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

Popular posts from this blog

java - Jasper subreport showing only one entry from the JSON data source when embedded in the Title band -

serialization - Convert Any type in scala to Array[Byte] and back -

SonarQube Plugin for Jenkins does not find SonarQube Scanner executable -