iOS Swift MapKit让用户做注解?

时间:2022-11-15 20:10:14

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:

我如何使它成为可能,在Swift中使用MapKit,让用户将注释从一个位置拖到另一个位置?我将注释视图设置为draggable,当我的map视图委托创建注释视图时,如下所示:

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?

结果是,用户可以拖拽注释——但只能拖拽一次。之后,注释就变得无法拖动,更糟糕的是,注释现在不再“属于”映射——当映射被滚动/窗格时,注释保持不变,而不是使用映射滚动/窗格。我做错了什么?

1 个解决方案

#1


20  

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:

仅通过将isDraggable设置为true来标记注释视图是不够的。您还必须在您的map视图委托中实现mapView(_:annotationView:didChange:fromOldState:)——而且(更重要的是)这个实现不能为空!相反,您的实现必须至少将拖放状态从传入参数传递到annotation视图,如下所示:

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.)

(非常感谢这个回答如此清晰地解释了这一点。我不能申请任何学分!我的回答只是把这段代码翻译成Swift。

#1


20  

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:

仅通过将isDraggable设置为true来标记注释视图是不够的。您还必须在您的map视图委托中实现mapView(_:annotationView:didChange:fromOldState:)——而且(更重要的是)这个实现不能为空!相反,您的实现必须至少将拖放状态从传入参数传递到annotation视图,如下所示:

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.)

(非常感谢这个回答如此清晰地解释了这一点。我不能申请任何学分!我的回答只是把这段代码翻译成Swift。