こんにちは、アプリケーション共同開発部の大江です。
2017年の9月に発表されたiOS11ではiPhoneXの登場に伴うSafe Areaの導入など開発者にとって大きな変化がありました。 あまり注目を浴びていませんが、iOS11ではMapKitも大幅に改良されました。 その中でも注目すべきは、これまではClusterやClusterKitなどのライブラリに頼ることが多かったアノテーションのクラスタリングがMapKitの機能として公式に追加されたことです。 そこで、今回はMapKitでアノテーションをクラスタリングする方法について紹介します。
実装方法
このサンプルコードではフェンリルの4つの所在地にアノテーションを配置します。
class FenrirOfficeAnnotation: NSObject, MKAnnotation { static let clusteringIdentifier = "FenrirOffice" let coordinate: CLLocationCoordinate2D let glyphText: String let glyphTintColor: UIColor let markerTintColor: UIColor init(_ coordinate: CLLocationCoordinate2D, glyphText: String, glyphTintColor: UIColor, markerTintColor: UIColor) { self.coordinate = coordinate self.glyphText = glyphText self.glyphTintColor = glyphTintColor self.markerTintColor = markerTintColor } } class ViewController: UIViewController, MKMapViewDelegate { @IBOutlet weak var mapView: MKMapView! override func viewDidLoad() { super.viewDidLoad() mapView.delegate = self let osaka = FenrirOfficeAnnotation(CLLocationCoordinate2D(latitude: 34.705563, longitude: 135.494851), glyphText: "大阪本社", glyphTintColor: .white, markerTintColor: .red) let tokyo = FenrirOfficeAnnotation(CLLocationCoordinate2D(latitude: 35.625018, longitude: 139.721239), glyphText: "東京支社", glyphTintColor: .white, markerTintColor: .magenta) let nagoya = FenrirOfficeAnnotation(CLLocationCoordinate2D(latitude: 35.174341, longitude: 136.912334), glyphText: "名古屋支社", glyphTintColor: .white, markerTintColor: .orange) let shimane = FenrirOfficeAnnotation(CLLocationCoordinate2D(latitude: 35.474979, longitude: 133.067409), glyphText: "島根支社", glyphTintColor: .brown, markerTintColor: .yellow) let annotations = [osaka, tokyo, nagoya, shimane] mapView.addAnnotations(annotations) } func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier, for: annotation) guard let markerAnnotationView = annotationView as? MKMarkerAnnotationView, let fenrirOfficeAnnotation = annotation as? FenrirOfficeAnnotation else { return annotationView } markerAnnotationView.clusteringIdentifier = FenrirOfficeAnnotation.clusteringIdentifier markerAnnotationView.glyphText = fenrirOfficeAnnotation.glyphText markerAnnotationView.glyphTintColor = fenrirOfficeAnnotation.glyphTintColor markerAnnotationView.markerTintColor = fenrirOfficeAnnotation.markerTintColor return markerAnnotationView } }
このように、MKAnnotationView.clusteringIdentifierに任意の文字列を設定するだけで、MKAnnotationViewが自動でクラスタリングされるようになります。
実行結果
マップのズームレベルを変更すると、以下のGIFアニメーションのようにアノテーションが自動でクラスタリングされます。
補足
clusteringIdentifier
MKAnnotationViewのオブジェクト毎にclusteringIdentifierを設定することができますが、clusteringIdentifierの値が異なるMKAnnotationViewはクラスタリングされません。
MKAnnotationView.clusteringIdentifierのデフォルト値は`nil`であり、clusteringIdentifierの値が`nil`であるMKAnnotationViewはクラスタリングの対象にはなりません。
MKMarkerAnnotationView
iOS11で登場したMKAnnotationViewのサブクラスです。
iOS11からはMKMapViewにMKMarkerAnnotationViewがデフォルトで登録されています。
このため、MKMapView.register(\_:forAnnotationViewWithReuseIdentifier:)を行わなくとも、MKMapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier, for: annotation)でMKMarkerAnnotationViewを取得できます。
MKMarkerAnnotationViewは、任意の文字や画像を表示できるglyphTextやglyphImage、アノテーションの色を変更できるmarkerTintColorなどのプロパティが用意されており、デザインを柔軟にカスタマイズすることができます。
まとめ
iOS11でMapKit標準機能となったアノテーションのクラスタリングについて紹介しました。
是非一度試してみてください。
参考
フェンリルの Facebook ページでは、最新トピックをお知らせしています。よろしければいいね!してください!