Skip to content

Commit b068aa8

Browse files
committed
[FEAT] #30 마커 클러스터 추가, 기본 마커 사용으로 변경
1 parent e96618f commit b068aa8

File tree

6 files changed

+69
-55
lines changed

6 files changed

+69
-55
lines changed

Pinit/Pinit/Views/Home/CustomAnnotationView.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ final class CustomAnnotationView: MKAnnotationView {
1414
override init(annotation: MKAnnotation?, reuseIdentifier: String?){
1515
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
1616
setupUI()
17+
clusteringIdentifier = "pinCluster"
1718
}
1819

1920
required init?(coder aDecoder: NSCoder) {
@@ -31,7 +32,7 @@ final class CustomAnnotationView: MKAnnotationView {
3132
let originalImage = UIImage(named: "recordPin2")!
3233
let resizedImage = resizeImage(originalImage, targetSize: CGSize(width: 40, height: 40))
3334
self.image = resizedImage
34-
self.centerOffset = CGPoint(x: 0, y: frame.size.height / 2)
35+
self.centerOffset = CGPoint(x: 0, y: self.bounds.minY - (frame.size.height / 2))
3536
self.layer.shadowColor = UIColor.black.withAlphaComponent(0.25).cgColor
3637
self.layer.shadowOpacity = 1
3738
self.layer.shadowRadius = 4
@@ -49,7 +50,6 @@ final class CustomAnnotationView: MKAnnotationView {
4950
titleLabel.attributedText = NSAttributedString(string: annotation.pinData.title, attributes: attributes)
5051
titleLabel.sizeToFit()
5152

52-
5353
titleLabel.snp.makeConstraints {
5454
$0.centerX.equalToSuperview()
5555
$0.top.equalTo(self.snp.bottom)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//
2+
// CustomClusterAnnotationView.swift
3+
// Pinit
4+
//
5+
// Created by 안정흠 on 3/21/25.
6+
//
7+
8+
import UIKit
9+
import MapKit
10+
11+
final class CustomClusterAnnotationView: MKMarkerAnnotationView {
12+
static let identifier = "CustomClusterAnnotationView"
13+
14+
override var annotation: MKAnnotation? {
15+
didSet {
16+
configure()
17+
}
18+
}
19+
20+
private func configure() {
21+
guard let cluster = annotation as? MKClusterAnnotation else { return }
22+
23+
// 1️⃣ 클러스터 안에 있는 핀 개수 텍스트로 표시
24+
glyphText = "\(cluster.memberAnnotations.count)"
25+
markerTintColor = .systemBlue // 원하는 색
26+
displayPriority = .defaultHigh
27+
}
28+
}

Pinit/Pinit/Views/Home/HomeViewController.swift

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,9 @@ class HomeViewController: UIViewController {
7171
animated: true
7272
)
7373
mapView.isRotateEnabled = false
74-
mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: CustomAnnotationView.identifier)
75-
// mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: "ClusterView")
74+
// mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: CustomAnnotationView.identifier)
75+
mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: "annotation")
76+
mapView.register(CustomClusterAnnotationView.self, forAnnotationViewWithReuseIdentifier: CustomClusterAnnotationView.identifier)
7677

7778
loadAnnotations()
7879
}
@@ -146,32 +147,23 @@ extension HomeViewController: MKMapViewDelegate {
146147
}
147148

148149
private func createCustomAnnotationView(for annotation: CustomAnnotation, in mapView: MKMapView) -> MKAnnotationView {
149-
let identifier = CustomAnnotationView.identifier
150-
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? CustomAnnotationView
151-
152-
if annotationView == nil {
153-
annotationView = CustomAnnotationView(annotation: annotation, reuseIdentifier: identifier)
154-
} else {
155-
annotationView?.annotation = annotation
156-
}
157-
annotationView?.configure(with: annotation)
158-
return annotationView!
150+
let view = mapView.dequeueReusableAnnotationView(withIdentifier: "annotation", for: annotation) as! MKMarkerAnnotationView
151+
view.annotation = annotation
152+
view.clusteringIdentifier = "pinCluster" // 클러스터링 가능하게
153+
154+
return view
159155
}
160156

161157
private func createClusterView(for cluster: MKClusterAnnotation) -> MKAnnotationView {
162-
let identifier = "ClusterView"
163-
var clusterView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView
158+
let identifier = CustomClusterAnnotationView.identifier
159+
var clusterView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? CustomClusterAnnotationView
164160

165161
if clusterView == nil {
166-
clusterView = MKMarkerAnnotationView(annotation: cluster, reuseIdentifier: identifier)
162+
clusterView = CustomClusterAnnotationView(annotation: cluster, reuseIdentifier: identifier)
167163
} else {
168164
clusterView?.annotation = cluster
169165
}
170166

171-
clusterView?.markerTintColor = .systemBlue
172-
clusterView?.glyphText = "\(cluster.memberAnnotations.count)" // 클러스터 내 개수 표시
173-
clusterView?.displayPriority = .defaultHigh // 클러스터를 우선적으로 표시
174-
175167
return clusterView!
176168
}
177169

@@ -183,6 +175,7 @@ extension HomeViewController: MKMapViewDelegate {
183175
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
184176
let visibleAnnotations = mapView.annotations(in: mapView.visibleMapRect)
185177
let visibleMarkers = visibleAnnotations.compactMap { $0 as? CustomAnnotation }
178+
// let visibleClusters = visibleAnnotations.compactMap{ $0 as? MKClusterAnnotation } // 할필요없음
186179
// BottomSheet의 CollectionView 업데이트
187180
adapter?.data = visibleMarkers.map{ $0.pinData }
188181
bottomSheet.collectionView.reloadData()

Pinit/Pinit/Views/Home/PinRecordCell.swift

Lines changed: 12 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -98,38 +98,19 @@ final class PinRecordCell: UICollectionViewCell {
9898
extension PinRecordCell {
9999
func captureMapSnapshotWithPin(center: CLLocationCoordinate2D, imageSize: CGSize, completion: @escaping (UIImage?) -> Void) {
100100
let options = MKMapSnapshotter.Options()
101-
options.region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.003, longitudeDelta: 0.003))
102-
options.size = imageSize
103-
options.mapType = .standard
104-
105-
let snapshotter = MKMapSnapshotter(options: options)
106-
snapshotter.start { snapshot, error in
107-
guard let snapshot = snapshot, error == nil else {
108-
print("스냅샷 생성 실패")
109-
completion(nil)
110-
return
111-
}
101+
options.region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.003, longitudeDelta: 0.003))
102+
options.size = imageSize
103+
options.mapType = .standard
112104

113-
// 핀 이미지 불러오기 (CustomAnnotationView에서 쓰는 이미지와 동일하게)
114-
guard let pinImage = UIImage(named: "recordPin2") else {
115-
print("핀 이미지 로드 실패")
116-
completion(nil)
117-
return
105+
let snapshotter = MKMapSnapshotter(options: options)
106+
snapshotter.start { snapshot, error in
107+
guard let snapshot = snapshot, error == nil else {
108+
print("스냅샷 생성 실패")
109+
completion(nil)
110+
return
111+
}
112+
113+
completion(snapshot.image)
118114
}
119-
120-
// 중심 좌표에 해당하는 이미지 상의 위치 계산
121-
let point = snapshot.point(for: center)
122-
let pinSize = CGSize(width: 30, height: 30)
123-
let pinOrigin = CGPoint(x: point.x - pinSize.width / 2, y: point.y - pinSize.height)
124-
125-
// 스냅샷에 핀 그리기
126-
UIGraphicsBeginImageContextWithOptions(snapshot.image.size, true, snapshot.image.scale)
127-
snapshot.image.draw(at: .zero)
128-
pinImage.draw(in: CGRect(origin: pinOrigin, size: pinSize))
129-
let finalImage = UIGraphicsGetImageFromCurrentImageContext()
130-
UIGraphicsEndImageContext()
131-
132-
completion(finalImage)
133-
}
134115
}
135116
}

Pinit/Pinit/Views/PastPin/PastPinViewController.swift

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import SnapKit
1212
final class PastPinViewController: UIViewController {
1313

1414
//MARK: - 모든 PinEntity를 가져옵니다.
15-
var pinData = PinEntity.sampleData
15+
var pinData: [PinEntity] = []
1616

1717
private let usecase: UseCase
1818

@@ -47,6 +47,18 @@ final class PastPinViewController: UIViewController {
4747
SetUI()
4848
setupAdapter()
4949
calendarUI()
50+
usecase.fetchPinsByDate(date: Date()) { items in
51+
self.adapter?.data = items
52+
self.PinCollectionView.reloadData()
53+
}
54+
}
55+
56+
override func viewWillAppear(_ animated: Bool) {
57+
super.viewWillAppear(animated)
58+
usecase.fetchPinsByDate(date: Date()) { items in
59+
self.adapter?.data = items
60+
self.PinCollectionView.reloadData()
61+
}
5062
}
5163

5264
//MARK: - init

Pinit/Pinit/Views/PinDetail/PinDetailViewController.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ final class PinDetailViewController: UIViewController {
7171
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005))
7272

7373
map.setRegion(region, animated: true)
74-
map.showsUserLocation = true
74+
map.showsUserLocation = false
75+
map.isUserInteractionEnabled = false
7576

7677
let annotation = MKPointAnnotation()
7778
annotation.coordinate = CLLocationCoordinate2D(latitude: lat, longitude: long) // San Francisco, CA
7879
annotation.title = pinEntity.title
79-
annotation.subtitle = pinEntity.weather
8080
map.addAnnotation(annotation)
8181

8282
return map

0 commit comments

Comments
 (0)