3

I am working on an old application and need to make changes in Mapview. Previously we need to show multiple annotations on mapview with same images on each pin but now we have to show different images on annotation view pins to display address. I am using the following code to display annotation pins but it always shows the same image on annotation pins.

Here is my code:

- (MKAnnotationView *) mapView:(MKMapView *)mapView1 viewForAnnotation:(id <MKAnnotation>) annotation
{
    NSLog(@"Eventtype Array is %@",eventTypeArray);
    MKAnnotationView * pinView = nil;
    if(annotation != _mapvw.userLocation)
    {
        static NSString * defaultPinID = @"pinId";
        pinView = (MKAnnotationView *)[_mapvw dequeueReusableAnnotationViewWithIdentifier:defaultPinID];

        if ( pinView == nil )
        {
            pinView = [[MKAnnotationView alloc]
                       initWithAnnotation:annotation reuseIdentifier:defaultPinID];
        }

    for ( int i=0; i<[eventTypeArray count]; i++)
        {
            eventTypeStr = [NSString stringWithFormat:@"%@",
                             [eventTypeArray objectAtIndex:i]];
            NSLog(@"Event Type is %@",eventTypeStr);

        if ([eventTypeStr isEqualToString:@"0"])
        {
            NSLog(@"Eventtype Array is %@",eventTypeStr);
            NSLog(@"Event Type is %@",eventTypeStr);
            pinView.canShowCallout = YES;
            pinView.image = [UIImage imageNamed:@"smiley.png"];
        }
        else if ([eventTypeStr isEqualToString:@"1"])
        {
            NSLog(@"Event Type is %@",eventTypeStr);
            pinView.canShowCallout = YES;
            pinView.image = [UIImage imageNamed:@"dollar1.png"];
        }
        else if ([eventTypeStr isEqualToString:@"2"])
        {
            NSLog(@"Event Type is %@",eventTypeStr);
            pinView.canShowCallout = YES;
            pinView.image = [UIImage imageNamed:@"donation.png"];
        }
        }
    }
    return pinView;
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
Abhinandan Pratap
  • 2,142
  • 1
  • 18
  • 39
  • Just finish the for loop before `if else`. P.S. There are many other many other improvements possible in this code (like using `switch` case instead of `if else`, enum / constant for your event identifier wtc.). Please consider a thorough review, and refactoring. – Swapnil Luktuke Jun 04 '20 at 14:22

1 Answers1

0

You’re iterating through your array of event types for every annotation, presumably always ending with the image associated for the last one in eventTypeArray.

Instead, you want the “event type” to be a property of the annotation. Then, when generating your annotation view, you can look at the annotation’s event type to know which image to use.

So, first, you haven’t done so already, you’d have an annotation that has an eventType property:

typedef NS_ENUM(NSUInteger, EventType) {
    EventTypeSmiley,
    EventTypeDollar,
    EventTypeDonation,
};

@interface EventAnnotation: MKPointAnnotation
@property (nonatomic) EventType eventType;
@end

@implementation EventAnnotation
@end

Now, in this case, I’m using an enumeration for my event types, but you can use whatever type you want. (Even if you stick with the event type array, I’d still use an enumeration to excise cryptic 0/1/2 values sprinkled throughout your code.)

Then, when you add annotations to your map, use this new annotation type, not MKPointAnnotation:

EventAnnotation *eventAnnotation = [[EventAnnotation alloc] init];
eventAnnotation.coordinate = coordinate;
eventAnnotation.title = @"Fund raiser";
eventAnnotation.eventType = EventTypeDollar;

Now that all of your annotations are EventAnnotation, you can have your viewForAnnotation act accordingly:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        return nil;
    }

    NSAssert([annotation isKindOfClass:[EventAnnotation class]], @"Was expecting event annotation”);  // obviously, handle non-EventAnnotation annotations however you want, but I’m going to catch failures for now

    static NSString *identifier = @"EventAnnotation";
    MKAnnotationView *annotationView = [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];

    if (!annotationView) {
        annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        annotationView.canShowCallout = YES;
    } else {
        annotationView.annotation = annotation;     // don't forget this line!
    }

    EventAnnotation *eventAnnotation = (EventAnnotation *)annotation;
    switch (eventAnnotation.eventType) {
        case EventTypeSmiley:
            annotationView.image = [UIImage imageNamed:@"smiley.png"];
            break;

        case EventTypeDollar:
            annotationView.image = [UIImage imageNamed:@"dollar1.png"];
            break;

        case EventTypeDonation:
            annotationView.image = [UIImage imageNamed:@"donation.png"];
            break;
    }

    return annotationView;
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Needless to say, `EventTypeSmiley` and `EventTypeDollar` are bad names, but I only had your image names to go from. You’d obviously use more meaningful enumeration value names. – Rob May 01 '20 at 16:41
  • when i try your code it returns 3 duplicate symbols for architecture x86_64 – Abhinandan Pratap May 02 '20 at 12:25
  • duplicate symbol _OBJC_CLASS_$_EventAnnotation in: , duplicate symbol _OBJC_METACLASS_$_EventAnnotation in:, duplicate symbol _OBJC_IVAR_$_EventAnnotation._eventType in: – Abhinandan Pratap May 02 '20 at 14:26
  • @AbhinandanPratap - Either you already have an `EventAnnotation` type in your project or you haven’t added this code correctly (added it twice somehow). – Rob May 02 '20 at 16:51
  • E.g. if you accidentally put the `@implementation` inside a `.h`, you could get this sort of problem. – Rob May 02 '20 at 16:59
  • Hello i need your help please https://stackoverflow.com/questions/62134167/ios-marker-title-display-only-last-index-of-the-array-for-multiple-markers – Abhinandan Pratap Jun 01 '20 at 14:28