Im try to customise my annotation in MapKit and SwiftUI
From the code below, I search in the map the specific coordinate (coord) and I display with my custom annotation.
1) I'm try to increase the size of the UIimage because to small (see the picture attached)and change the color, any idea how?
2)in the map after the app start it display only the icon, after I tap on the icon the annotation appear, any idea how to display immediately my annotation without tapping?
3)now in the annotation I manage to display title and subtitle, how to display also the coordinate
struct MapView: UIViewRepresentable {
let Mm : MapManager
let coord = CLLocationCoordinate2D(latitude: 52.28792, longitude: 4.73415327)
class Coordinator: NSObject, MKMapViewDelegate {
var parent : MapView
init(_ parent: MapView) {
self.parent = parent
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "TESTING NOTE")
annotationView.canShowCallout = true
annotationView.image = UIImage(systemName: "location.circle")
return annotationView
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> MKMapView {
let view = MKMapView(frame: .zero)
Mm.georeverseCoordinate(coord) { (pin) in
if let pinOK = pin {
view.removeAnnotation(pinOK)
view.mapType = MKMapType.satellite
let span = MKCoordinateSpan(latitudeDelta: 0.04, longitudeDelta: 0.04)
let region = MKCoordinateRegion(center: self.coord, span: span)
view.setRegion(region, animated: true)
view.delegate = context.coordinator
view.addAnnotation(pinOK)
}
}
return view
}
func updateUIView(_ view: MKMapView, context: Context) {
}
}
Map manager
class MapManager: NSObject, CLLocationManagerDelegate {
static let shared = MapManager()
func georeverseCoordinate(_ coord: CLLocationCoordinate2D , closure: @escaping (Pin?) -> Void) {
let location = CLLocation(latitude: coord.latitude, longitude: coord.longitude)
let geocoder = CLGeocoder()
geocoder.reverseGeocodeLocation(location) { (arrayResponse, error) in
if let errorTest = error {
debugPrint(errorTest.localizedDescription)
closure(nil)
return
}
if let arrayPins = arrayResponse {
if let valorePinArray = arrayPins.first {
debugPrint(valorePinArray.locality!)
debugPrint(valorePinArray.isoCountryCode!)
let pin = Pin(title: valorePinArray.locality!, subtitle: valorePinArray.isoCountryCode!, coordinate: valorePinArray.location!.coordinate)
closure(pin)
}
else { closure(nil) }
}
else { closure(nil) }
}
}
}
Pin Model
class Pin:NSObject, MKAnnotation {
var title : String?
var subtitle : String?
var coordinate : CLLocationCoordinate2D
var color: UIColor?
init(title: String?, subtitle: String?, coordinate: CLLocationCoordinate2D) {
self.title = title
self.subtitle = subtitle
self.coordinate = coordinate
}
}
1) - There seems to be a bug that makes it difficult to change the colour of SF Symbols with tintColor
and a specific rendering mode but there is a workaround that also allows an easy way to change the size of the symbol.
In mapView:viewFor annotation
add the following:
annotationView.canShowCallout = true
annotationView.image = UIImage(systemName: "location.circle")?.withTintColor(.systemGreen, renderingMode: .alwaysOriginal)
let size = CGSize(width: 40, height: 40)
annotationView.image = UIGraphicsImageRenderer(size:size).image {
_ in annotationView.image!.draw(in:CGRect(origin:.zero, size:size))
}
2) - To show the callout as soon as the annotation is added to the map, use selectAnnotation
.
view.addAnnotation(pinOK)
view.selectAnnotation(pinOK, animated: true)
3) - The coordinate is available when your annotation is being constructed so you can simply change the init in the Pin class:
init(title: String?, subtitle: String?, coordinate: CLLocationCoordinate2D) {
self.coordinate = coordinate
self.title = "\(coordinate.latitude) : \(coordinate.longitude)"
self.subtitle = subtitle
}