1
votes

I wonder how to set different images to annotation pins on mapview. The difference between the following questions

viewForAnnotation confusion and customizing the pinColor iteratively

Swift different images for Annotation

is that my array of images is generated dynamically with regard to server response. There is no fixed size of the array, so switch/case construction is not a good idea. Moreover, I'm not sure how to apply the solution with custom class aforementioned in topic above. I'm aware that it would be better to post a comment to one of the questions asked before, but unfortunately I'm too rookie at the moment to do that(too few points).

This is the for loop performed inside functions that shows map:

for var r=0;r<arrayOfRestaurants.count;r++
    {

        var summonRestaurant:NSDictionary = arrayOfRestaurants[r] as NSDictionary
        var nearbyRestaurant = Restaurant(nearbyRestaurants:summonRestaurant)
        var latRestaurant=(nearbyRestaurant.latitude as NSString).doubleValue
        var longRestaurant=(nearbyRestaurant.longitude as NSString).doubleValue
        var locationOfRestaurant = CLLocationCoordinate2D(
            latitude: latRestaurant as CLLocationDegrees, longitude: longRestaurant as CLLocationDegrees)
        var lunchArray: NSArray = nearbyRestaurant.lunch as NSArray
        var annotation = MKPointAnnotation()

        annotation.setCoordinate(locationOfRestaurant)
        annotation.title = nearbyRestaurant.name + "  " + nearbyRestaurant.distance + " km"
        map.addAnnotation(annotation)
}

And here is viewForAnnotation delegate method(quite identical to the method used in aforementioned threads):

func mapView(map: MKMapView!,
    viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

        if annotation is MKUserLocation {
            //return nil so map view draws "blue dot" for standard user location
            return nil
        }

        let reuseId = "pin"

        var pinView = map.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
        if pinView == nil {
            pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
            pinView!.canShowCallout = true
            pinView!.animatesDrop = true
            pinView!.pinColor = .Purple

            pinView!.image = globalImageArray[0]

            }
        else {
            pinView!.annotation = annotation
        }

        return pinView
}

As you can see, I assigned a certain image to pinView which is globalImageArray[0], but I look for a solution that let me iterate over the globalImageArray and assign a certain image to each pin.

I'd be glad to receive any help, thanks in advance!

1
What is the relationship between an annotation and a pin? How do you know which image goes with each annotation?Paulw11
images in array go in the same sequence as pins are created, each item of arrayOfRestaurants has a corresponding item in globalImageArraytheDC
So rather than using an MKPointAnnotation you need to create your own class that adopts the MKAnnotation protocol and store the image in a property of he annotation itself. This is basically the approach in the second question you linkedPaulw11
I'm afraid I'm not sure how to do it well. Would you mind elaboration through answering the question? thanks!theDC

1 Answers

4
votes

First, you need to create your own class that adopts the MKAnnotation protocol for your annotations -

class RestaurantAnnotation : NSObject, MKAnnotation {
    var coordinate: CLLocationCoordinate2D
    var title: String
    var subtitle: String
    var image: UIImage?

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

Then, use instances of this class when you add the annotation and set the image -

for var r=0;r<arrayOfRestaurants.count;r++
    {

        var summonRestaurant:NSDictionary = arrayOfRestaurants[r] as NSDictionary
        var nearbyRestaurant = Restaurant(nearbyRestaurants:summonRestaurant)
        var latRestaurant=(nearbyRestaurant.latitude as NSString).doubleValue
        var longRestaurant=(nearbyRestaurant.longitude as NSString).doubleValue
        let locationOfRestaurant = CLLocationCoordinate2D(
            latitude: latRestaurant as CLLocationDegrees, longitude: longRestaurant as CLLocationDegrees)
        var lunchArray: NSArray = nearbyRestaurant.lunch as NSArray

        let title = nearbyRestaurant.name + "  " + nearbyRestaurant.distance +" km"
        var annotation = RestaurantAnnotation(coordinate, title:title, subtitle:"")
        annotation.image = globalImageArray[r]
        map.addAnnotation(annotation)
}

Now, in your view for annotation you can access the image -

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
    if !(annotation is RestaurantAnnotation) {
        return nil
    }

    let reuseId = "restaurant"
    var anView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId)
    if anView == nil {
        anView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
        anView.canShowCallout = true
    }
    else {
        anView.annotation = annotation
    }

    let restaurantAnnotation = annotation as RestaurantAnnotation

    if (restaurantAnnotation.image != nil) {
            anView.image = restaurantAnnotation.image!
            anView.image.layer.setCornerRadius(8.0)
            anView.image.layer.clipsToBounds=true
        }
        else {
         // Perhaps set some default image
        }

    return anView
}