diff --git a/Pinit/Pinit/Models/PinEntity.swift b/Pinit/Pinit/Models/PinEntity.swift index c00c271..efcc887 100644 --- a/Pinit/Pinit/Models/PinEntity.swift +++ b/Pinit/Pinit/Models/PinEntity.swift @@ -9,14 +9,14 @@ import UIKit struct PinEntity { let pin_id: UUID - let title: String + var title: String let latitude: Double let longitude: Double let address: String let date: Date let weather: String - let description: String? - let mediaPath: UIImage? + var description: String? + var mediaPath: UIImage? static let sampleData: [PinEntity] = [ PinEntity(pin_id: UUID(uuidString: "b44a6eaf-a5f8-426c-8200-0cf93a18c2ca")!, diff --git a/Pinit/Pinit/Models/ProducerEntity.swift b/Pinit/Pinit/Models/ProducerEntity.swift index ee98527..b9fbc8f 100644 --- a/Pinit/Pinit/Models/ProducerEntity.swift +++ b/Pinit/Pinit/Models/ProducerEntity.swift @@ -26,7 +26,7 @@ extension PinEntity { //데이터 부분들 PinEntity( - pin_id: UUID(), + pin_id: UUID(uuidString: "11111111-1111-1111-1111-111111111111")!, title: "JustHm", latitude: 37.9244577, longitude: 128.800009,//본인 지역의 의,경도 @@ -38,7 +38,7 @@ extension PinEntity { ), PinEntity( - pin_id: UUID(), + pin_id: UUID(uuidString: "22222222-2222-2222-2222-222222222222")!, title: "Ikhwan0204", latitude: 37.506610, longitude: 126.885332, @@ -50,7 +50,7 @@ extension PinEntity { ), PinEntity( - pin_id: UUID(), + pin_id: UUID(uuidString: "33333333-3333-3333-3333-333333333333")!, title: "IntakHan304", latitude: 37.434981, longitude: 126.902328, @@ -62,7 +62,7 @@ extension PinEntity { ), PinEntity( - pin_id: UUID(), + pin_id: UUID(uuidString: "44444444-4444-4444-4444-444444444444")!, title: "HISEHOONAN", latitude: 37.508645, longitude: 126.703513, diff --git a/Pinit/Pinit/Views/Home/CustomAnnotationView.swift b/Pinit/Pinit/Views/Home/CustomAnnotationView.swift index 462cd21..3db925b 100644 --- a/Pinit/Pinit/Views/Home/CustomAnnotationView.swift +++ b/Pinit/Pinit/Views/Home/CustomAnnotationView.swift @@ -14,6 +14,7 @@ final class CustomAnnotationView: MKAnnotationView { override init(annotation: MKAnnotation?, reuseIdentifier: String?){ super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) setupUI() + clusteringIdentifier = "pinCluster" } required init?(coder aDecoder: NSCoder) { @@ -31,7 +32,7 @@ final class CustomAnnotationView: MKAnnotationView { let originalImage = UIImage(named: "recordPin2")! let resizedImage = resizeImage(originalImage, targetSize: CGSize(width: 40, height: 40)) self.image = resizedImage - self.centerOffset = CGPoint(x: 0, y: frame.size.height / 2) + self.centerOffset = CGPoint(x: 0, y: self.bounds.minY - (frame.size.height / 2)) self.layer.shadowColor = UIColor.black.withAlphaComponent(0.25).cgColor self.layer.shadowOpacity = 1 self.layer.shadowRadius = 4 @@ -49,7 +50,6 @@ final class CustomAnnotationView: MKAnnotationView { titleLabel.attributedText = NSAttributedString(string: annotation.pinData.title, attributes: attributes) titleLabel.sizeToFit() - titleLabel.snp.makeConstraints { $0.centerX.equalToSuperview() $0.top.equalTo(self.snp.bottom) diff --git a/Pinit/Pinit/Views/Home/CustomClusterAnnotationView.swift b/Pinit/Pinit/Views/Home/CustomClusterAnnotationView.swift new file mode 100644 index 0000000..59de55c --- /dev/null +++ b/Pinit/Pinit/Views/Home/CustomClusterAnnotationView.swift @@ -0,0 +1,28 @@ +// +// CustomClusterAnnotationView.swift +// Pinit +// +// Created by 안정흠 on 3/21/25. +// + +import UIKit +import MapKit + +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 } + + // 1️⃣ 클러스터 안에 있는 핀 개수 텍스트로 표시 + glyphText = "\(cluster.memberAnnotations.count)" + markerTintColor = .systemBlue // 원하는 색 + displayPriority = .defaultHigh + } +} diff --git a/Pinit/Pinit/Views/Home/HomeViewController.swift b/Pinit/Pinit/Views/Home/HomeViewController.swift index 91e17a9..806629e 100644 --- a/Pinit/Pinit/Views/Home/HomeViewController.swift +++ b/Pinit/Pinit/Views/Home/HomeViewController.swift @@ -71,8 +71,9 @@ class HomeViewController: UIViewController { animated: true ) mapView.isRotateEnabled = false - mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: CustomAnnotationView.identifier) - // mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: "ClusterView") +// mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: CustomAnnotationView.identifier) + mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: "annotation") + mapView.register(CustomClusterAnnotationView.self, forAnnotationViewWithReuseIdentifier: CustomClusterAnnotationView.identifier) loadAnnotations() } @@ -146,32 +147,23 @@ extension HomeViewController: MKMapViewDelegate { } private func createCustomAnnotationView(for annotation: CustomAnnotation, in mapView: MKMapView) -> MKAnnotationView { - let identifier = CustomAnnotationView.identifier - var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? CustomAnnotationView - - if annotationView == nil { - annotationView = CustomAnnotationView(annotation: annotation, reuseIdentifier: identifier) - } else { - annotationView?.annotation = annotation - } - annotationView?.configure(with: annotation) - return annotationView! + let view = mapView.dequeueReusableAnnotationView(withIdentifier: "annotation", for: annotation) as! MKMarkerAnnotationView + view.annotation = annotation + view.clusteringIdentifier = "pinCluster" // 클러스터링 가능하게 + + return view } private func createClusterView(for cluster: MKClusterAnnotation) -> MKAnnotationView { - let identifier = "ClusterView" - var clusterView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKMarkerAnnotationView + let identifier = CustomClusterAnnotationView.identifier + var clusterView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? CustomClusterAnnotationView if clusterView == nil { - clusterView = MKMarkerAnnotationView(annotation: cluster, reuseIdentifier: identifier) + clusterView = CustomClusterAnnotationView(annotation: cluster, reuseIdentifier: identifier) } else { clusterView?.annotation = cluster } - clusterView?.markerTintColor = .systemBlue - clusterView?.glyphText = "\(cluster.memberAnnotations.count)" // 클러스터 내 개수 표시 - clusterView?.displayPriority = .defaultHigh // 클러스터를 우선적으로 표시 - return clusterView! } @@ -183,6 +175,7 @@ extension HomeViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) { let visibleAnnotations = mapView.annotations(in: mapView.visibleMapRect) let visibleMarkers = visibleAnnotations.compactMap { $0 as? CustomAnnotation } +// let visibleClusters = visibleAnnotations.compactMap{ $0 as? MKClusterAnnotation } // 할필요없음 // BottomSheet의 CollectionView 업데이트 adapter?.data = visibleMarkers.map{ $0.pinData } bottomSheet.collectionView.reloadData() diff --git a/Pinit/Pinit/Views/Home/PinRecordCell.swift b/Pinit/Pinit/Views/Home/PinRecordCell.swift index 8d82c16..698c05a 100644 --- a/Pinit/Pinit/Views/Home/PinRecordCell.swift +++ b/Pinit/Pinit/Views/Home/PinRecordCell.swift @@ -6,6 +6,7 @@ // import UIKit +import MapKit final class PinRecordCell: UICollectionViewCell { //그림자 뷰 추가 @@ -42,8 +43,23 @@ final class PinRecordCell: UICollectionViewCell { func configure(model: PinEntity) { pinDateLabel.text = model.date.formatted() pinTitleLabel.text = model.title - thumbnailImageView.image = UIImage(systemName: "house") - //thumbnailImageView.image = model.mediaPath ?? UIImage(systemName: "house") + + if let image = model.mediaPath { + thumbnailImageView.image = image + } + else { + captureMapSnapshotWithPin( + center: CLLocationCoordinate2D( + latitude: model.latitude, + longitude: model.longitude + ), + imageSize: CGSize( + width: contentView.frame.height, + height: contentView.frame.width + )) { image in + self.thumbnailImageView.image = image ?? UIImage(systemName: "house") + } + } setupLayout() } @@ -77,3 +93,24 @@ final class PinRecordCell: UICollectionViewCell { } } + + +extension PinRecordCell { + func captureMapSnapshotWithPin(center: CLLocationCoordinate2D, imageSize: CGSize, completion: @escaping (UIImage?) -> Void) { + let options = MKMapSnapshotter.Options() + options.region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.003, longitudeDelta: 0.003)) + options.size = imageSize + options.mapType = .standard + + let snapshotter = MKMapSnapshotter(options: options) + snapshotter.start { snapshot, error in + guard let snapshot = snapshot, error == nil else { + print("스냅샷 생성 실패") + completion(nil) + return + } + + completion(snapshot.image) + } + } +} diff --git a/Pinit/Pinit/Views/PastPin/PastPinViewController.swift b/Pinit/Pinit/Views/PastPin/PastPinViewController.swift index 116c388..0c94362 100644 --- a/Pinit/Pinit/Views/PastPin/PastPinViewController.swift +++ b/Pinit/Pinit/Views/PastPin/PastPinViewController.swift @@ -12,7 +12,7 @@ import SnapKit final class PastPinViewController: UIViewController { //MARK: - 모든 PinEntity를 가져옵니다. - var pinData = PinEntity.sampleData + var pinData: [PinEntity] = [] private let usecase: UseCase @@ -47,6 +47,18 @@ final class PastPinViewController: UIViewController { SetUI() setupAdapter() calendarUI() + usecase.fetchPinsByDate(date: Date()) { items in + self.adapter?.data = items + self.PinCollectionView.reloadData() + } + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + usecase.fetchPinsByDate(date: Date()) { items in + self.adapter?.data = items + self.PinCollectionView.reloadData() + } } //MARK: - init diff --git a/Pinit/Pinit/Views/PinDetail/PinDetailViewController.swift b/Pinit/Pinit/Views/PinDetail/PinDetailViewController.swift index 7f1951c..e626b7c 100644 --- a/Pinit/Pinit/Views/PinDetail/PinDetailViewController.swift +++ b/Pinit/Pinit/Views/PinDetail/PinDetailViewController.swift @@ -71,12 +71,12 @@ final class PinDetailViewController: UIViewController { let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005)) map.setRegion(region, animated: true) - map.showsUserLocation = true + map.showsUserLocation = false + map.isUserInteractionEnabled = false let annotation = MKPointAnnotation() annotation.coordinate = CLLocationCoordinate2D(latitude: lat, longitude: long) // San Francisco, CA annotation.title = pinEntity.title - annotation.subtitle = pinEntity.weather map.addAnnotation(annotation) return map diff --git a/Pinit/Pinit/Views/PinEdit/PinEditViewController.swift b/Pinit/Pinit/Views/PinEdit/PinEditViewController.swift index bb5c87f..801ad7a 100644 --- a/Pinit/Pinit/Views/PinEdit/PinEditViewController.swift +++ b/Pinit/Pinit/Views/PinEdit/PinEditViewController.swift @@ -162,9 +162,9 @@ final class PinEditViewController: UIViewController, UITextViewDelegate { contentTextView.inputAccessoryView = keyboardToolBar contentTextView.delegate = self - closeButton.addTarget(PinEditViewController.self, action: #selector(dismissButtonTapped), for: .touchUpInside) + closeButton.addTarget(self, action: #selector(dismissButtonTapped), for: .touchUpInside) saveButton.addTarget(self, action: #selector(saveButtonTapped), for: .touchUpInside) - cameraButton.addTarget(PinEditViewController.self, action: #selector(cameraButtonTapped), for: .touchUpInside) + cameraButton.addTarget(self, action: #selector(cameraButtonTapped), for: .touchUpInside) self.view.addSubviews(mapView, saveButton, contentTextView, titleTextField, cameraButton, weatherButton, dateButton, closeButton) @@ -218,8 +218,10 @@ final class PinEditViewController: UIViewController, UITextViewDelegate { //MARK: 저장버튼 눌림 @objc private func saveButtonTapped() { - guard let newPin = pinEntity else { return } - isAdded?(newPin) + pinEntity?.title = titleTextField.text ?? "" + pinEntity?.description = contentTextView.text ?? "" +// pinEntity?.mediaPath = image ???? + isAdded?(pinEntity!) dismiss(animated: true) }