如何获得可拖延的MKAnnotationView没有任何延迟?

下面的代码工作,并给我一个可拖动的注释视图。 但是,我注意到注释视图从一开始就不可拖动,而是仅在手指在注释视图上暂停一小段时间之后。 直接进入拖动运动时,拖动不会影响注释视图,而是会影响地图。 它当然不会像拖拉一样。 无论是在设备上还是在模拟器中。

ViewController(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 } for 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 } } 

我不认为你可以改变可拖动的延迟,但你可以禁用它并添加你自己的没有延迟(或更短的延迟)的拖动手势:

 func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? { if annotation is 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 this to whatever you 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) } } 

顺便说一下,如果您要更改注释的coordinate ,则需要将dynamic关键字添加到自定义类coordinate声明中,以便发出相应的KVO通知。

 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() } } 

请注意,在此示例中,我将延迟设置为零。 这意味着如果您点击注释(“显示标注”的典型用户界面),这可能会阻止其正常工作。 它会将此视为非常短的阻力。 这就是标准UI在拖动之前需要延迟长按的原因。

因此,出于这个原因,我个人会犹豫是否覆盖上面显示的这种行为,因为它将与最终用户熟悉的标准地图行为不同。 如果您的地图的行为与用户设备上的任何其他地图的行为不同,则可能会令人感到沮丧。