xyk blog

最近は iOS 開発の記事が多めです。

マップ(MKMapView)上にピンを立てる

検証環境:
Xcode 12.4
Swift 5.3.2
iOS Deployment Target 14.4

マップ(MKMapView)を表示してピンを立てるだけの簡単な実装例。

マップビューにピンを追加するには、MKAnnotationプロトコルを適合したクラスを用意して、位置情報CLLocationCoordinate2Dを設定する。
そしてそのアノテーションをマップビューに追加すればよい。

以下サンプルでは、デフォルトで用意されているアノテーションクラスのMKPointAnnotationを使用し、マップ上で長押しした地点にピンを立てるようにした。

f:id:xyk:20210408120838p:plain

import UIKit
import MapKit

class ViewController: UIViewController {

    let mapView = MKMapView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // マップビュー張り付け
        view.addSubview(mapView)
        mapView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            mapView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
            mapView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            mapView.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor),
            mapView.rightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.rightAnchor),
        ])
        
        mapView.delegate = self
        
        // マップの中心緯度経度と表示範囲を指定
        let center = CLLocationCoordinate2D(latitude: 35.68358493824179, longitude: 139.750327090532)
        mapView.region = MKCoordinateRegion(center: center, latitudinalMeters: 500, longitudinalMeters: 500)
        
        // マップ上の長押しした地点にピンを立てるジェスチャーを追加
        let longPress = UILongPressGestureRecognizer(target: self, action: #selector(didLongPress))
        longPress.minimumPressDuration = 0.5
        mapView.addGestureRecognizer(longPress)
    }
    
    @objc private func didLongPress(_ gesture: UILongPressGestureRecognizer) {
        guard gesture.state == .began else { return }
        
        // MKPointAnnotation を生成してマップビューに追加する
        let annotation = MKPointAnnotation()
        let location = gesture.location(in: mapView)
        let coordinate = mapView.convert(location, toCoordinateFrom: mapView)
        annotation.coordinate = coordinate
        annotation.title = "\(mapView.annotations.count + 1)"
        mapView.addAnnotation(annotation)
    }
}

extension ViewController: MKMapViewDelegate {
    
    // ピンのビューである MKAnnotationView に変更を加えるためのデリゲートメソッド。変更する必要がなければこのデリゲートは省略してもよい。
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

        let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier, for: annotation)
        annotationView.displayPriority = .required // 縮小時にピンを省略せず表示させる
        return annotationView
    }
}