-
Notifications
You must be signed in to change notification settings - Fork 121
/
Copy pathViewController.swift
executable file
·155 lines (130 loc) · 5.57 KB
/
ViewController.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//
// ViewController.swift
// Example
//
// Created by Lasha Efremidze on 4/13/17.
// Copyright © 2017 efremidze. All rights reserved.
//
import UIKit
import MapKit
import Cluster
class ViewController: UIViewController {
@IBOutlet weak var mapView: MKMapView! {
didSet {
mapView.region = .init(center: region.center, span: .init(latitudeDelta: region.delta, longitudeDelta: region.delta))
}
}
@IBOutlet weak var segmentedControl: UISegmentedControl!
lazy var manager: ClusterManager = { [unowned self] in
let manager = ClusterManager()
manager.delegate = self
manager.maxZoomLevel = 17
manager.minCountForClustering = 3
manager.clusterPosition = .nearCenter
return manager
}()
let region = (center: CLLocationCoordinate2D(latitude: 37.787994, longitude: -122.407437), delta: 0.1)
override func viewDidLoad() {
super.viewDidLoad()
manager.add(MeAnnotation(coordinate: region.center))
addAnnotations()
}
@IBAction func addAnnotations(_ sender: UIButton? = nil) {
// Add annotations to the manager.
let annotations: [Annotation] = (0..<100000).map { i in
let annotation = Annotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: region.center.latitude + drand48() * region.delta - region.delta / 2, longitude: region.center.longitude + drand48() * region.delta - region.delta / 2)
return annotation
}
manager.add(annotations)
manager.reload(mapView: mapView)
}
@IBAction func removeAnnotations(_ sender: UIButton? = nil) {
manager.removeAll()
manager.reload(mapView: mapView)
}
@IBAction func valueChanged(_ sender: UISegmentedControl) {
removeAnnotations()
addAnnotations()
}
}
extension ViewController: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if let annotation = annotation as? ClusterAnnotation {
let index = segmentedControl.selectedSegmentIndex
let identifier = "Cluster\(index)"
let selection = Selection(rawValue: index)!
return mapView.annotationView(selection: selection, annotation: annotation, reuseIdentifier: identifier)
} else if let annotation = annotation as? MeAnnotation {
let identifier = "Me"
let annotationView = mapView.annotationView(of: MKAnnotationView.self, annotation: annotation, reuseIdentifier: identifier)
annotationView.image = .me
return annotationView
} else {
let identifier = "Pin"
let annotationView = mapView.annotationView(of: MKPinAnnotationView.self, annotation: annotation, reuseIdentifier: identifier)
annotationView.pinTintColor = .green
return annotationView
}
}
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
manager.reload(mapView: mapView) { finished in
print(finished)
}
}
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
guard let annotation = view.annotation else { return }
if let cluster = annotation as? ClusterAnnotation {
var zoomRect = MKMapRect.null
for annotation in cluster.annotations {
let annotationPoint = MKMapPoint(annotation.coordinate)
let pointRect = MKMapRect(x: annotationPoint.x, y: annotationPoint.y, width: 0, height: 0)
if zoomRect.isNull {
zoomRect = pointRect
} else {
zoomRect = zoomRect.union(pointRect)
}
}
mapView.setVisibleMapRect(zoomRect, animated: true)
}
}
func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
views.forEach { $0.alpha = 0 }
UIView.animate(withDuration: 0.35, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: [], animations: {
views.forEach { $0.alpha = 1 }
}, completion: nil)
}
}
extension ViewController: ClusterManagerDelegate {
func cellSize(for zoomLevel: Double) -> Double? {
return nil // default
}
func shouldClusterAnnotation(_ annotation: MKAnnotation) -> Bool {
return !(annotation is MeAnnotation)
}
}
extension ViewController {
enum Selection: Int {
case count, imageCount, image
}
}
extension MKMapView {
func annotationView(selection: ViewController.Selection, annotation: MKAnnotation?, reuseIdentifier: String) -> MKAnnotationView {
switch selection {
case .count:
let annotationView = self.annotationView(of: CountClusterAnnotationView.self, annotation: annotation, reuseIdentifier: reuseIdentifier)
annotationView.countLabel.backgroundColor = .green
return annotationView
case .imageCount:
let annotationView = self.annotationView(of: ImageCountClusterAnnotationView.self, annotation: annotation, reuseIdentifier: reuseIdentifier)
annotationView.countLabel.textColor = .green
annotationView.image = .pin2
return annotationView
case .image:
let annotationView = self.annotationView(of: MKAnnotationView.self, annotation: annotation, reuseIdentifier: reuseIdentifier)
annotationView.image = .pin
return annotationView
}
}
}
class MeAnnotation: Annotation {}