iOS Swift MapKit如何让用户可以拖动标注?

16

我该如何使用Swift中的MapKit实现用户在地图上将注释从一个位置拖到另一个位置?当我的地图视图委托创建注释视图时,我已将注释视图设置为可拖动,代码如下:

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
}
结果是用户可以“有点”拖动注释 - 但仅限一次。之后,注释将无法拖动,更糟糕的是,注释现在不再“属于”地图 - 当地图被滚动/平移时,注释保持不变而不是随地图滚动/平移。我做错了什么?
1个回答

29

单纯地将注释视图的 isDraggable 设置为 true 是不够的。您还必须在地图视图代理中实现 mapView(_:annotationView:didChange:fromOldState:) 方法——更重要的是,这个方法的实现不能是空的! 相反,您的实现至少必须将来自传入参数的拖动状态传达给注释视图,就像这样:

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

一旦您这样做,用户就可以正确地拖动注释。

(非常感谢这个答案清晰地解释了这一点。我不能声称有任何功劳!我的答案仅是将该代码翻译为Swift的结果。)


2
这个解决方案是否仍适用于iOS 11?我按照这个解决方案,但是mapView(_:annotationView:didChange:fromOldState:)方法从未被调用。 - mert
@mert - 这个方法仍然被称为“called”(尽管MKAnnotationViewDragState的引用现在显然是MKAnnotationView.DragState)。 - Rob
话虽如此,我已经在各种设备上测试了可拖动注释,从 iOS 10 开始,这种方法似乎并不需要。也许只有在旧版的 iOS 中才需要? - Rob
1
@Rob 是的,在我的书中,mapView(_:annotationView:didChange:fromOldState:) 的讨论因为不再必要已经被剪掉了几个版本。 - matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接