0

I would like to toggle the visibility of the title of my MKPointAnnotation after I tap the pin. I tried changing the title directly in
func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) but it tells me that it's only a get property and I cannot change it inside of my Coordinator class.

Any help would be much appreciated!

Here is the relevant code...

import SwiftUI
import MapKit
import CoreLocationUI

struct MapViewTest: UIViewRepresentable {
    
    @EnvironmentObject var viewModel: MapViewModel
    
    @Binding var region: MKCoordinateRegion
    @Binding var lineCoordinates: [[CLLocationCoordinate2D]]
    
    func makeUIView(context: Context) -> MKMapView {
        let mapView = MKMapView()
        mapView.delegate = context.coordinator
        mapView.region = region
        mapView.showsUserLocation = true
        
        return mapView
    }
    
    func updateUIView(_ view: MKMapView, context: Context) {
        view.setRegion(region, animated: true)
        
        for i in viewModel.locations {
            let pin = MKPointAnnotation()
            pin.coordinate = i.coordinate
            pin.title = i.name
            view.addAnnotation(pin)
        }
        
        for i in lineCoordinates{
            let polyline = MKPolyline(coordinates: i, count: i.count)
            view.addOverlay(polyline)
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }
    
    
}

class Coordinator: NSObject, MKMapViewDelegate {
        
    var parent: MapViewTest
    
    init(_ parent: MapViewTest) {
        self.parent = parent
    }
    
    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
        
    }
    
    func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
        if let routePolyline = overlay as? MKPolyline {
            let renderer = MKPolylineRenderer(polyline: routePolyline)
            renderer.strokeColor = UIColor.systemBlue
            renderer.lineWidth = 10
            return renderer
        }
        return MKOverlayRenderer()
    }
}
RapsIn4
  • 91
  • 5
  • I am confused as to your question. Your title says visibility, but you also talk about "changing the title". Do you want to show and hide the title, or do you want to rename the title of the annotation? – Yrb Dec 29 '21 at 01:27
  • My apologies, I want to show/hide the title. – RapsIn4 Dec 29 '21 at 01:31
  • @RapsIn4 was your particular requirement really about also hiding the title inside the default callout that is generated when you select an annotation? – Alnitak Dec 01 '22 at 14:07

1 Answers1

1

Whenever you are making a MapKit annotation, you should include func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?. This function allows you to configure your pins, but it also allows you to reuse unused pins. Whenever a pin disappears from a map (scrolling around, etc.), that pin is not destroyed, but it is held to be reused in another pin is needed. This saves processor and memory.

In your Coordinator class add the following function:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    // create a unique identifier for pin reuse
    let identifier = "Placemark"
    
    // see if there already is a created pin
    var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)
    
    if annotationView == nil {
        // there wasn't a pin, so we make a new one
        annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
        
        // this is where your title is allowed to be shown when tapping the pin
        annotationView?.canShowCallout = true
        
        // this gives you an information button in the callout if needed
        // if you use the rightCalloutAccessoryView you must implement:
        // func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl)
        annotationView?.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
    } else {
        // we have an old annotation, so update it
        annotationView?.annotation = annotation
    }
    
    return annotationView
}
Yrb
  • 8,103
  • 2
  • 14
  • 44
  • I noticed that it turned My Location into a pin as well, can I change it so that it shows the dot instead of the pin just for my location on the map? – RapsIn4 Dec 29 '21 at 02:04
  • Never mind, I figured it out myself. Thanks again! – RapsIn4 Dec 29 '21 at 02:14