Swift MapViewにピンを立てる


Map上のピンはMKPointAnnotationというオブジェクトで管理・表現されている。


ピンを立てる

シンプルなピンの場合、MKPointAnnotationをMapViewにaddAnnotationすることですぐに実装できる。

let mapView = MKMapView()
let annotation = MKPointAnnotation()
//ピンの位置
let latitude = 35.72949166949532
lett longitude = 139.77815044444452
annotation.coordinate = CLLocationCoordinate2DMake(latitude, longitude)
//ピンにメッセージを付随する
annotation.title = "タイトル"
annotation.subtitle = "サブタイトル"
//ピンを追加
mapView.addAnnotation(annotation)


ピンに吹き出しViewを付随する

上記で設定したタイトルやサブタイトルをピン専用の吹き出しView(MKPinAnnotationView)の中に入れることができる。また、MKPinAnnotationViewの中にはUIButtonを設置することも可能。

吹き出しはピン押下後に現れる。

f:id:letitride:20190819185541p:plain:h400


こちらはMKMapViewDelegateのviewFor annotationメソッドを実装してMKAnnotationViewをreturnする。

extension MapViewController: MKMapViewDelegate{
    
    //アノテーションビューを返すメソッド
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        //アノテーションビューを作成する。
        let pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: nil)
        
        //吹き出しを表示可能に。
        pinView.canShowCallout = true
        
        let button = UIButton()
        button.frame = CGRect(x:0,y:0,width:40,height:40)
        button.setTitle("OK", for: .normal)
        button.setTitleColor(UIColor.white, for: .normal)
        button.backgroundColor = UIColor.blue
        button.addTarget(self, action: #selector(sendLocation), for: .touchUpInside)
        //右側にボタンを追加
        pinView.rightCalloutAccessoryView = button
        return pinView
    }

    //OKボタン押下時の処理
    @objc func sendLocation(){
    }
}

MapViewにdelegateを渡すのを忘れずに。

let mapView = MKMapView()
mapView.delegate = self
//...中略
mapView.addAnnotation(annotation)


ピン設置時に吹き出しも同時に表示する

ピン押下せずに吹き出しを表示するケース。

MapViewにselectedAnnotationsというプロパティがあるので、それに対象のannotationを設定しておけば、タップなしで吹き出しが表示されるている状態になる。

let mapView = MKMapView()
mapView.delegate = self
//...中略
mapView.addAnnotation(annotation)
mapView.selectedAnnotations = [annotation]


ピンの削除

ピンの削除はremoveAnnotationメソッドで設置したannotationを渡して削除する

mapView.addAnnotation(annotation)
//...何らかの処理など
mapView.removeAnnotation(annotation)