0

I want to create MKPointAnnotaion's with the identifier number in the annotation overlay instead of the pin. So a 1 for the first annotation, a 2 for the second annotation, etc.

First, I added an MKPointAnnotation to the mapView based on a UILongPressGestureRecognizer.

With the mapView(_:viewFor:) I want to style those Annotations. This works to a certain extent but brings us to my problem:

I created a class CustomAnnotation to add an identifier to my MKPointAnnotaion:

class CustomAnnotation: MKPointAnnotation {
    var identifier: Int!
}

And I set the identifier when registering UILongPressGesture:

let annotation = CustomAnnotation()
annotation.identifier = mapView.annotations.count

Then I use mapView(_:viewFor:) to change the appearance of my MKPointAnnotaion's. But I do not know how to set annotationView.glyphText so that it uses the identifier defined before for every created annotation individually.

extension ViewController: MKMapViewDelegate {
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        guard annotation is CustomAnnotation else { return nil }

        let annotationView = MKMarkerAnnotationView()
        annotationView.glyphTintColor = .white
        annotationView.glyphText = "44"
            
        return annotationView
    }
}
m_s
  • 37
  • 6
  • 1
    See https://www.kodeco.com/7738344-mapkit-tutorial-getting-started#toc-anchor-009 your annotationView has a field annotation. you set that field in the code you've shown. Then you subclass your annotation and store in it whatever you want, including your index. – Gerd Castan May 18 '23 at 20:03

1 Answers1

0

Thank you @Gerd Castan for your reference to the very extensive tutorial at kodeco

In the following I give a brief overview how I solved my problem - it might help someone in the future.

First of all I changed the type of my CustomAnnotation class from a MKPointAnnotationto an MKAnnotation. Now it is actually applicable to every Map Annotation use case.

class CustomAnnotation: NSObject, MKAnnotation {
    @objc dynamic var coordinate: CLLocationCoordinate2D
    var title:String?
    var subtitle: String?
    var identifier: Int?
    
    init(coordinate:CLLocationCoordinate2D,
         title:String?, subtitle:String?, identifier:Int?) {
        self.coordinate = coordinate
        self.title = title
        self.subtitle = subtitle
        self.identifier = identifier
   }
}

Then I created a class for the view representation of the CustomAnnotation called CustomAnnotationView. In this case the type is an MKMarkerAnnotationView but you can also use MKAnnotationView if you do not want the representation of the Annotations as markers.

class CustomAnnotationView: MKMarkerAnnotationView {
    override var annotation: MKAnnotation?{
        willSet{
            
            guard let marker = newValue as? CustomAnnotation else { return }

            if let number = marker.identifier {
               let alphabeticRepresentation = UnicodeScalar(number+1+64)!
               glyphText = String(alphabeticRepresentation)
            }
            
        }
    }
    
}

One annotation to the code cell above:

  1. If you do not want an alphabetic representation in your marker, then just delete the following line of code in the example above let alphabeticRepresentation = UnicodeScalar(number+1+64)!

In my UILongPressureGesture handler I set the identifier, so only the number of CustomAnnotaion's are counted.

let identifier = mapView.annotations.filter{ $0 is CustomAnnotation }.count

In viewDidload() of the MapViewController I registered the CustomAnnotationView

mapView.register(CustomAnnotationView.self,
                  forAnnotationViewWithReuseIdentifier:
                  MKMapViewDefaultAnnotationViewReuseIdentifier)

That's it.

m_s
  • 37
  • 6