1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Mapkit】ClusterAnnotationに含まれる情報を取得する方法

Posted at

はじめに

MKMapKitを使うと簡単に地図やピンが描画できてとても便利ですが、
クラスター化されたピンをタップした際のデータ取得に少し苦労したので、簡単にまとめておきます。

環境

Xcode 12.4
Swift 5.3.2

実現したかった事

  • 緯度軽度とIDの情報を持ったピンを生成
  • ピンのUIはシンプルに、文字の表示もしない
  • 全てのピンは物理接触でクラスター化され、クラスターピンには数字を表示
  • ピンをタップしたら画面遷移させ、その際ピンに含まれるIDを渡す

実装

まずは、カスタムアノテーションを作る。

class CustomAnnotation: NSObject, MKAnnotation {
    // クラスターID
    static let clusteringIdentifier = "locationCluster"
    // ピンの緯度軽度
    let coordinate: CLLocationCoordinate2D
    // ピンのID
    let title: String?

    init(_ coordinate: CLLocationCoordinate2D, id: Int) {
        self.coordinate = coordinate
        title = String(id)
    }
}

次に地図画面の実装(関係する箇所のみ)

extension MapViewController: MKMapViewDelegate {
    // ピンを地図に描画する(初期表示やデータ更新時)
    private func drawPinsOnMap() {
        let span = MKCoordinateSpan(latitudeDelta: spanLatitudeDelta, longitudeDelta: spanLongitudeDelta)
        let center = CLLocationCoordinate2DMake(centerLatitude, centerLongitude)
        let region = MKCoordinateRegion(center: center, span: span)
        mapView.region = region
        var annotations: [MKAnnotation] = []
        mapView.removeAnnotations(mapView.annotations)
        let mapData = viewModel.dataArray.value   //データ取得
        guard mapData.count > 0 else { return }
        for data in mapData {
            let pin = CustomAnnotation(CLLocationCoordinate2DMake(data.latitude, data.longitude), id: data.id)
            annotations.append(pin)
        }
        mapView.addAnnotations(annotations)
    }

    // アノテーションビューの生成
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        if annotation is MKUserLocation {
            return nil
        } else if annotation is MKClusterAnnotation {
            let clusterAnnoationView = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier, for: annotation)
            guard let safeCluster = clusterAnnoationView as? MKMarkerAnnotationView else { return clusterAnnoationView }
            safeCluster.titleVisibility = .hidden
            safeCluster.subtitleVisibility = .hidden
            return safeCluster
        }

        let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier, for: annotation)

        guard let markerAnnotationView = annotationView as? MKMarkerAnnotationView, let _ = annotation as? CustomAnnotation else {
            return annotationView
        }
        markerAnnotationView.clusteringIdentifier = CustomAnnotation.clusteringIdentifier
        markerAnnotationView.titleVisibility = .hidden
        markerAnnotationView.subtitleVisibility = .hidden
        return markerAnnotationView
    }

    // 地図上のピン押下時の処理
    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
        var idList: [Int] = []
        // ここでクラスターピンか単体ピンか確認して処理を変える
        if let cluster = view.annotation as? MKClusterAnnotation {
            let annotations = cluster.memberAnnotations
            for annotation in annotations {
                guard let title = annotation.title as? String else { continue }
                guard let id = Int(title) else { continue }
                idList.append(id)
            }
        } else {
            guard let pin = view.annotation else { return }
            guard let title = pin.title as? String else { return }
            guard let id = Int(title) else { return }
            photoIdList.append(id)
        }

        // ★ ここでidListを持って画面遷移させる

        // 必要に応じてピンのセレクト状態を解除する
        mapView.deselectAnnotation(view.annotation, animated: true)
    }
}

結果

if let cluster = view.annotation as? MKClusterAnnotation {
    let annotations = cluster.memberAnnotations
}

でクラスターピンの持っている情報が取得できました。

感想

結果的に大したことなかった実装でしたが、クラスターピンからなかなかピンの情報が取得できず、ドキュメントを読みながら色々工夫してやっとできました。

参考記事

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?