Skip to content

[iOS] MapKit으로 타임라인 보여주기

TaeHyun edited this page Dec 13, 2023 · 6 revisions

🗺️ 지도에서 타임라인을 보여주자



traveline 서비스에는 타임라인 화면에서 지도로 보기를 누르면 지도에서 해당 일자의 타임라인을 보여주는 기능이 있습니다.

지도에서 타임라인 장소의 위치에 마커를 표시하고, 마커를 선택하면 해당 위치의 타임라인 카드가 노출됩니다.

그리고 해당 타임라인 카드를 선택하면 타임라인의 상세 글을 확인할 수 있는 흐름이에요!


🤔 어떤 지도를 쓸까?

저희는 위 기능을 구현하기 위해 지도를 사용하게 되었는데요,
지도에서 큰 Interaction이 많지 않고, 장소에 마커와 해당 장소의 정보만 가지고 있을 수 있으면 되었기 때문에
비교적 가볍게 사용할 수 있고, Annotation을 이용해 정보를 저장할 수 있는 MapKit을 선택하게 되었습니다 😉


📍 TLMarkerAnnotation 만들기

타임라인 장소마다 해당 위,경도에 마커를 찍어주고, 해당 마커를 선택했을 때 타임라인 카드를 노출하고 다시 선택 시 상세 화면으로 이동하기 위해 TLMarkerAnnotation에 정보를 가지고 있게 했습니다.

final class TLMarkerAnnotation: NSObject, MKAnnotation {
    
    let cardInfo: TimelineCardInfo

    @objc dynamic var coordinate: CLLocationCoordinate2D
    
    init(cardInfo: TimelineCardInfo, coordinate: CLLocationCoordinate2D) {
        self.cardInfo = cardInfo
        self.coordinate = coordinate
    }
    
}

🚨 마커 이미지의 위치?

실제로 지도에 마커를 그렸을 때 마커 이미지의 위치가 기대한 것과 다르게 나오는 문제가 있었습니다.

마커 이미지의 아랫변 가운데 부분이 위치를 가리키도록 하고 싶었는데, 현재는 마커 이미지의 중앙이 위치를 가리키고 있었어요.

그 과정에서 annotationView의 centerOffset을 바꿔줄 수 있다는 걸 알게 되어 아래와 같이 처리해줄 수 있었습니다! 🙂

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    
    ...

    if let imageHeight = annotationView?.frame.height {
        annotationView?.centerOffset = .init(x: 0, y: -imageHeight / 2)
    }
    
    return annotationView
}

🚨 클러스터링?

타임라인을 더 많이 만들게되고 마커의 수가 많아져 마커 간의 간격이 좁아지면, 지도에서 해당 위치의 마커를 선택하기 어렵다는 것을 느끼게 되었습니다.

그래서 현재 MapKit Annotation의 displayPriority를 활용해 간단하게 클러스터링을 적용해보려고 하고 있습니다! 🙌

Clone this wiki locally