🌐 MapKit의 마커에 클러스터를 사용해보자!

728x90

 

 

GitHub - EST-iOS-TEAM2/Pinit: ESTSoft 2차 팀프로젝트

ESTSoft 2차 팀프로젝트. Contribute to EST-iOS-TEAM2/Pinit development by creating an account on GitHub.

github.com

 

맵킷 사용해보자!

Mapkit의 기본기능만을 활용해 어노테이션 + 클러스터를 구현했다.

425917600-3e6edf63-5949-42e4-8a20-bfd159e90145.png

처음에는 마커 이미지도 커스텀으로 적용했지만, 다른뷰에서 이미 기본마커로 구현을 했기에...
Home 화면의 지도 역시 기본마커로 만들기로 했다.

 

클러스터 마커 생성하기

클러스터 마커를 생성하는건 기본 마커 커스텀을 하는 방법과 유사하다 (아예 똑같기도 하다)

MKMarkerAnnotationView 를 상속받아 구현해주면 된다.

final class CustomClusterAnnotationView: MKMarkerAnnotationView {
    static let identifier = "CustomClusterAnnotationView"

    override var annotation: MKAnnotation? {
        didSet {
            configure()
        }
    }

    private func configure() {
        guard let cluster = annotation as? MKClusterAnnotation else { return }

        // 클러스터 안에 있는 핀 개수 텍스트로 표시
        glyphText = "\(cluster.memberAnnotations.count)"
        markerTintColor = .systemBlue // 원하는 색
        displayPriority = .defaultHigh
    }
}

클러스터 마커가 생성되면 여기 CustomClusterAnnotationView 의 설정에 맞게 클러스터 마커가 생성된다.

 

클러스터 마커 추가하기

가장 먼저 사용할 맵에 클러스터뷰를 등록해준다

mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: "annotation")
mapView.register(CustomClusterAnnotationView.self, forAnnotationViewWithReuseIdentifier: CustomClusterAnnotationView.identifier)

그 다음 MKMapViewDelegate를 채택해 마커가 추가됐을때 보여줄 마커뷰를 어떻게 생성해서 보여줄지 정의하면 된다.

쉽게 TableView or CollectionView의 cellForRowAt 으로 생각하면 된다.

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    // 사용자 위치 마커는 무시
    guard !(annotation is MKUserLocation) else { return nil }

    if let cluster = annotation as? MKClusterAnnotation { // 클러스터 가능한 경우 여기에 잡힘
        return createClusterView(for: cluster)
    }
    if let customAnnotation = annotation as? CustomAnnotation {
        return createCustomAnnotationView(for: customAnnotation, in: mapView)
    }

    return nil

}

MKMapDelegate에서 마커들중 클러스터가 가능한게 있으면 MKClusterAnnotation 타입으로 캐스팅이 가능하게 온다!

그래서 일반 마커와 클러스터된 마커를 구분해서 생성할 수 있게 분기처리를 했다.

private func createCustomAnnotationView(for annotation: CustomAnnotation, in mapView: MKMapView) -> MKAnnotationView {
    let view = mapView.dequeueReusableAnnotationView(withIdentifier: "annotation", for: annotation) as! MKMarkerAnnotationView
    view.annotation = annotation
    view.clusteringIdentifier = "pinCluster" // 클러스터 가능하게 id 설정
    // id가 동일한 어노테이션 끼리만 클러스터 됌
    return view
}

일반 마커를 생성할때 clusteringIdentifier를 설정해두면 알아서 클러스터를 해준다.

즉 클러스터 안할 마커가 따로있다면 또는 클러스터 묶음을 따로따로 두고싶다면 저 아이디를 관리해주면 된다.

private func createClusterView(for cluster: MKClusterAnnotation) -> MKAnnotationView {
    let identifier = CustomClusterAnnotationView.identifier
    var clusterView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? CustomClusterAnnotationView

    if clusterView == nil {
        clusterView = CustomClusterAnnotationView(annotation: cluster, reuseIdentifier: identifier)
    } else {
        clusterView?.annotation = cluster
    }

    return clusterView!
}

그리고 마지막으로 addAnnotation 하고 데이터를 추가해주면 클러스터도 잘 되는 마커들을 볼 수 있다!

 

728x90