MKMapViewの標準calloutの代わりに、独自Viewを使った際の挙動でちょっと詰まったのでメモします。
事象
マップ上の同じピンを2回連続でタップしても独自Viewが呼び出せない。
内容
MKMapviewのannotation(ピン)をタップした時にcallout(吹き出し)を使わずに独自のビューを表示する場合、calloutを表示しないようcanCallout
にfalse
を設定して、MKMapViewDelegateのdidSelectでViewの呼び出しを行うかと思います。
calloutを呼び出さないようにする
func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
for view in views {
view.canShowCallout = false
}
}
ピンをタップして独自Viewを呼び出す処理(今回はViewControllerを表示してます)
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView){
let modalViewController = ViewController()
modalViewController.delegate = self
self.present(modalViewController, animated: false, completion: nil)
}
modalViewControllerから呼び出し元(MKMapViewが表示されているViewController)に戻り、再度同じピンをタップしてもmodalViewControllerは開かれませんでした(didSelectも呼ばれていない)。
対処法
canShowCallout
がfalse
でもピンをタップした時にcalloutが開かれたような状態になっているようなので、同じピンへのdisSelectが効かなかったように思われました。
ですので、ピンの選択を解除する処理をdidSelect内に入れたところ、独自View表示と同時にピンの選択(calloutの表示)も解除されるため、同じピンへの2回連続タップも効くようになりました。
didSelectにピンの選択解除処理を入れる
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView){
let modalViewController = ViewController()
modalViewController.delegate = self
self.present(modalViewController, animated: false, completion: nil)
// ピンの選択を解除
for annotaion in mapView.selectedAnnotations {
mapView.deselectAnnotation(annotaion, animated: false)
}
}
ちなみに setSelected
でも良さそうでしたが、こちらは効果がありませんでした。