Search code examples
iosmapkitmkmapviewmkannotation

Adding different images to different annotation views in xcode


I am trying to add different images to different annotation views, in other words, i want a unique pic to correspond to each unique pin. Here is what I am trying:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    NSLog(@"welcome into the map view annotation");

    // if it's the user location, just return nil.
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    // try to dequeue an existing pin view first
    static NSString* AnnotationIdentifier = @"AnnotationIdentifier";
    MKPinAnnotationView* pinView = [[[MKPinAnnotationView alloc]
                                     initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
    pinView.animatesDrop=YES;
    pinView.canShowCallout=YES;
    pinView.pinColor=MKPinAnnotationColorPurple;


    UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
    [rightButton setTitle:annotation.title forState:UIControlStateNormal];
    [rightButton addTarget:self
                    action:@selector(showDetails:)
          forControlEvents:UIControlEventTouchUpInside];
    pinView.rightCalloutAccessoryView = rightButton;

    if (CLLocationCoordinate2D == theCoordinate1) {

    UIImageView *profileIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Jeff.png"]];
    pinView.leftCalloutAccessoryView = profileIconView;
    [profileIconView release];

    }else if(CLLocationCoordinate2D = theCoordinate2) {
        UIImageView *profileIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Pierce.png"]];
        pinView.leftCalloutAccessoryView = profileIconView;
        [profileIconView release];
    }

I am getting an error for the line where I write

if (CLLocationCoordinate2D == theCoordinate1) {

I am not sure quite what is wrong, nor can i figure out another way to identify the individual annotation. Any help is greatly appreciated!!


Solution

  • That line gives an error because CLLocationCoordinate2D is a type of struct and theCoordinate1 is, I assume, a variable of type CLLocationCoordinate2D. You can't compare the two.

    What you are trying to do is compare the coordinates of the current annotation for which a view is being requested to the coordinates in theCoordinate1. To do that, if you must, you need something like this:

    if ((annotation.coordinate.latitude == theCoordinate1.latitude) 
            && (annotation.coordinate.longitude == theCoordinate1.longitude)) {
    

    However, I don't recommend comparing floating point numbers that way even if it "works" sometimes. If you must compare coordinates, use CLLocation's distanceFromLocation: method and see if the distance between the two is below some threshold like 10.0 meters.

    Another way to check if the annotation is the one you're looking for is to keep a reference to the annotation itself (the one you passed to the addAnnotation: method) and then you can do if (annotation == theAnnotation1).

    If you don't want to keep a reference to the annotations, you can also check if the title of the annotation is the one your're looking for (if ([annotation.title isEqualToString:@"Jeff"])).

    The best way is to add a custom property (ideally an int) to a custom annotation class and check for that in viewForAnnotation.


    A few other unrelated things:

    • Instead of doing addTarget, handle the button press in the map view's own calloutAccessoryControlTapped delegate method which will give a reference to the annotation (see How to find which annotation send showDetails? for example).
    • You have a comment to "dequeue" but you're not doing it. It's recommended to use dequeueReusableAnnotationViewWithIdentifier in viewForAnnotation to re-use views (see EXC_BAD_ACCESS with MKPinAnnotationView for example).