How to enable black mode in Google Maps in iOS

Issue #246

Use GMSMapStyle https://developers.google.com/maps/documentation/android-sdk/styling
Export styling json from https://mapstyle.withgoogle.com/

1
2
let mapStyleUrl = Bundle.main.url(forResource: "mapStyle", withExtension: "json")!
mapView.mapStyle = try? GMSMapStyle(contentsOfFileURL: mapStyleUrl)

To change overall color, search for mostly "elementType": "geometry" and "featureType": "water"

1
2
3
4
5
6
7
8
{
"elementType": "geometry",
"stylers": [
{
"color": "#424242"
}
]
}
1
2
3
4
5
6
7
8
9
{
"featureType": "water",
"elementType": "geometry",
"stylers": [
{
"color": "#2E2E2E"
}
]
}

How to zoom in double in MapKit

Issue #183

1
2
3
4
5
6
7
8
9
10
11
12
func zoomInDouble(coordinate: CLLocationCoordinate2D) {
let region = mapView.region
let zoomInRegion = MKCoordinateRegion(
center: coordinate,
span: MKCoordinateSpan(
latitudeDelta: region.span.latitudeDelta * 0.5,
longitudeDelta: region.span.longitudeDelta * 0.5
)
)

mapView.setRegion(zoomInRegion, animated: true)
}

How to select cluster annotation in MapKit

Issue #182

1
2
3
4
5
6
7
8
9
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
guard let coordinate = view.annotation?.coordinate else {
return
}

if (view.annotation is MKClusterAnnotation) {
zoomInDouble(coordinate: coordinate)
}
}

How to cluster annotations in MapKit in iOS 11

Issue #181

https://developer.apple.com/documentation/mapkit/mkannotationview/decluttering_a_map_with_mapkit_annotation_clustering

1
2
3
4
5
6
7
8
9
10
11
final class AnnotationView: MKMarkerAnnotationView {
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)

clusteringIdentifier = String(describing: ClusterView.self)
}

required init?(coder aDecoder: NSCoder) {
fatalError()
}
}
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
final class ClusterView: MKAnnotationView {
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
displayPriority = .defaultHigh
}

required init?(coder aDecoder: NSCoder) {
fatalError()
}

override func prepareForDisplay() {
super.prepareForDisplay()

guard let annotation = annotation as? MKClusterAnnotation else {
return
}

let count = annotation.memberAnnotations.count
image = self.image(annotation: annotation, count: count)
}

func image(annotation: MKClusterAnnotation, count: Int) -> UIImage? {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 40.0, height: 40.0))
image = renderer.image { _ in
UIColor.purple.setFill()
UIBezierPath(ovalIn: CGRect(x: 0.0, y: 0.0, width: 40.0, height: 40.0)).fill()
let attributes: [NSAttributedString.Key: Any] = [
NSAttributedString.Key.foregroundColor: UIColor.white,
NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 20.0)
]

let text = "\(count)"
let size = text.size(withAttributes: attributes)
let rect = CGRect(x: 20 - size.width / 2, y: 20 - size.height / 2, width: size.width, height: size.height)
text.draw(in: rect, withAttributes: attributes)
}

return image
}
}
1
mapView.register(ClusterView.self, forAnnotationViewWithReuseIdentifier: String(describing: ClusterView.self))