L_Cleo
L_Cleo

Reputation: 1527

Custom Annotation View showing default pin on MKMapView

I'm trying to render a custom annotation view with a custom image. However I'm having trouble with the rendering of the custom annotations, as they are rendering as default map red pins as so:

enter image description here

I looked quite a few articles/tutorials/stack questions in regards of it but still couldn't find the problem in my code. I created a MKPointAnnotation class

class FriendAnnotation: MKPointAnnotation {

  var type: FriendModeType?

  init(
    coordinate: CLLocationCoordinate2D,
    title: String,
    subtitle: String,
    type: FriendModeType
  ) {
    super.init()
    super.coordinate = coordinate
    super.title = title
    super.subtitle = subtitle
    self.type = type
  }

Then created a custom MKAnnotationView for my FriendAnnotation

class FriendAnnotationView: MKAnnotationView {
  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
  }
  
  override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
    super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
    guard
      let friendAnnotation = self.annotation as? FriendAnnotation else {
        return
    }
    
      image = friendAnnotation.type?.image()
  }
}

the image is then retrieved from the enum's specific function

enum FriendModeAnnotationType: Int {
    //enums
    
    func image() -> UIImage {
      switch self {
      case .searching:
        return UIImage(imageLiteralResourceName: "trophy")
      case .offering:
          return UIImage(imageLiteralResourceName: "trophy")
      case .none:
          return UIImage(imageLiteralResourceName: "trophy")
      }
    }
    
    //...
}

For testing purposes, yes it's the same image, and yes I already use the image in other parts of my code where it correctly renders

Then I created the MKMapViewDelegate for the map view

class Coordinator: NSObject, CLLocationManagerDelegate, MKMapViewDelegate {
        
        var friendStore: FriendStore
        
        init(friendStore: FriendStore) {
            self.friendStore = friendStore
        }
        
        func mapView(
          _ mapView: MKMapView,
          viewFor annotation: MKAnnotation
        ) -> MKAnnotationView? {
           print("Making the annotation view!!!")
           let annotationView = FriendAnnotationView(
            annotation: annotation,
            reuseIdentifier: "User")
          annotationView.canShowCallout = true
          return annotationView
        }

        
        func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
            switch manager.authorizationStatus {
               //..some code
            }
        }
        
        func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            //...some code
        }
    }

And here I am with the red pin rendering instead of the trophy. As a matter of fact the print statement within the mapView function is not even getting printed, so I guess it's never calling that method

All the updates to the map correctly go through as the pins (even if just red) they actually render

Am I missing something here?

Upvotes: 1

Views: 526

Answers (1)

L_Cleo
L_Cleo

Reputation: 1527

I figured myself that the mapView requires a delegate itself and not only the manager. So although the coordinator was inheriting both MKMapViewDelegate and CLLocationManagerDelegate I still had to set the mapView's delegate.

If anyone encounters the same problem just add the delegate to the mapView too (in my case it would be):

map.delegate = context.coordinator

This just took my entire day to figure out, so sad...

Upvotes: 0

Related Questions