Search code examples
swift4mapkitannotation

MapKit custom image for multiple annotations


I have news objects and I want to customize the news annotation according to the news category. Without the switch statement, if I just write annotationView?.image = UIImage(named: "ic_sports"), all annotations; images shows the sport image. How can I get the news category id for that annotation so I can change the annotation image according to that id?

The console prints Log annotation is news for all of the annotations.

News:

class News: NSObject, MKAnnotation {

    let coordinate: CLLocationCoordinate2D
    var categoryId: Int
    var title: String?

    // Other variables and init function ...

    func getCategoryId() -> Int {
        return categoryId
    }

}

MapViewController:

function parse(json: JSON) {
    // ...
    let news = News(categoryId: data["category_id"].intValue,
                    title: data["title"].stringValue,
                    coordinate: coordinate)
    self.mapView.addAnnotation(news)
}


func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

    if annotation is News {
        print("Log annotation is news")
    } else {
        print("Log annotation NOT news")
    }

    var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "newsAnnotationView")
    if annotationView == nil {
        annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "newsAnnotationView")
    }
    switch(annotation.getCategoryId()) {
    case 1: // Other
        annotationView?.image = UIImage(named: "ic_other")
        break;
    case 2: // sports
        annotationView?.image = UIImage(named: "ic_sports")
        break;
    case 3: // education
        annotationView?.image = UIImage(named: "ic_education")
        break;
    case 4: // crime
        annotationView?.image = UIImage(named: "ic_crime")
        break;
    case 5: // health
        annotationView?.image = UIImage(named: "ic_health")
        break;
    default:
        break;
    }
    annotationView?.canShowCallout = true
    return annotationView
}

Solution

  • I have solved this by creating a news object and give it the value of annotation as News, then use news.getCategoryId()

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    
        let news = annotation as! News
    
        var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "newsAnnotationView")
    
        if annotationView == nil {
            annotationView = MKAnnotationView(annotation: news, reuseIdentifier: "newsAnnotationView")
        }
    
        switch(news.getCategoryId()) {
        case 1: // Other
            annotationView?.image = UIImage(named: "ic_other")
            break;
        case 2: // sports
            annotationView?.image = UIImage(named: "ic_sports")
            break;
        case 3: // education
            annotationView?.image = UIImage(named: "ic_education")
            break;
        case 4: // crime
            annotationView?.image = UIImage(named: "ic_crime")
            break;
        case 5: // health
            annotationView?.image = UIImage(named: "ic_health")
            break;
        default:
            break;
        }
    
        annotationView?.canShowCallout = true
        return annotationView
    }