LoginSignup
6
5

More than 3 years have passed since last update.

【Swift】MkMarkerAnnotationViewをドラッグ可能にする

Posted at

概要

アプリのMap上でMkMarkerAnnotationViewをドラッグさせる実装についてです。
ドラッグ可能なMKPinAnnotationViewを実装する方法はたくさん出てくるのですが、MkMarkerAnnotationViewのままドラッグさせる方法が見つからなかったので、今回記事にしました。

イメージは下記の通りです。
qiita_20190917_1.gif

実行環境

【Xcode】 11.0(Xcode11 GM Seed)
【Swift】 5
【iOS】 13.0

実装

実装は以下の通りです。

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()
        mapView.delegate = self

        // annotationをmapに設定
        let annotation = MKPointAnnotation()
        annotation.coordinate = point
        mapView.addAnnotation(annotation)
    }

    /// annotation生成時に行うannotationの設定
    /// - Parameter mapView: annotationが生成されたmapView
    /// - Parameter annotation: 生成されたannotation
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let markerAnnotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "myPin")
        markerAnnotationView.isDraggable = true
        return markerAnnotationView
    }
}

今回の肝はannotation生成時のdelegateメソッドであるfunc mapView(MKMapView, viewFor: MKAnnotation) -> MKAnnotationView?の一行目です。
MKMarkerAnnotationViewのオブジェクトを生成し、isDraggabletrueに設定することで、そのままドラッグすることができるようになります。
自分は最初MKMarkerAnnotationViewの存在がわからず悩んでいたんですが、簡単に実装できましたね。

おまけ

上記だけだと物足りないので、

  1. MKMarkerAnnotationViewをタップして吹き出しを表示する
  2. ドラッグすると吹き出しが消える
  3. ドラッグし終わると吹き出しが再表示する

以上の機能を実装してみます。

qiita_20190917_2.gif

    @IBOutlet weak var mapView: MKMapView!
    let annotation = MKPointAnnotation()

    override func viewDidLoad() {
        super.viewDidLoad()

        mapView.delegate = self

        // mapの縮尺設定
        let point = CLLocationCoordinate2D(latitude: 35.681_236, longitude: 139.767_125)
        let region = MKCoordinateRegion(center: point, latitudinalMeters: 1000, longitudinalMeters: 1000)
        mapView.setRegion(region, animated: true)

        // annotationをmapに設定
        annotation.coordinate = point
        annotation.title = "東京駅"
        annotation.subtitle = "東京都千代田区丸の内1丁目"
        mapView.addAnnotation(annotation)
    }

    /// annotation生成時に行うannotationの設定
    /// - Parameter mapView: annotationが生成されたmapView
    /// - Parameter annotation: 生成されたannotation
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        let markerAnnotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "myPin")
        markerAnnotationView.isDraggable = true
        markerAnnotationView.canShowCallout = true
        markerAnnotationView.rightCalloutAccessoryView = UIButton(type: UIButton.ButtonType.detailDisclosure)
        return markerAnnotationView
    }

    /// annotationドラッグ時に行う処理
    /// - Parameter mapView:annotationが生成されてたmapView
    /// - Parameter view: annotation
    /// - Parameter newState: 次の状態
    /// - Parameter oldState: 前の状態
    public func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, didChange newState: MKAnnotationView.DragState, fromOldState oldState: MKAnnotationView.DragState) {
        if newState == .starting {
            mapView.deselectAnnotation(annotation, animated: true)
        }
    }
6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5