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回だけです。その後、注釈をドラッグできなくなり、さらに悪いことに、注釈はマップに「属し」なくなります。マップをスクロール/パンすると、注釈はマップと一緒にスクロール/パンするのではなく、静止したままになります。私は何が間違っているのですか?
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に翻訳しただけです。)