【问题标题】:Adding multiple annotations with multiple images on mapview in ios Objective-c?在 ios Objective-c 中的 mapview 上添加多个带有多个图像的注释?
【发布时间】:2020-08-14 11:57:18
【问题描述】:

我正在开发一个旧应用程序,需要在 Mapview 中进行更改。以前我们需要在 mapview 上显示多个注释,每个 pin 上都有相同的图像,但现在我们必须在 annotation view pin 上显示不同的图像以显示地址。我正在使用以下代码来显示注释引脚,但它始终在注释引脚上显示相同的图像。

这是我的代码:

- (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;
}

【问题讨论】:

  • if else之前完成for循环。附言此代码中还有许多其他可能的改进(例如使用switch 大小写而不是if else,事件标识符wtc 的枚举/常量)。请考虑彻底审查和重构。

标签: ios objective-c mkmapview mkannotation mkannotationview


【解决方案1】:

您正在遍历每个注释的事件类型数组,大概总是以与eventTypeArray 中的最后一个关联的图像结束。

相反,您希望“事件类型”成为注释的属性。然后,在生成注释视图时,您可以查看注释的事件类型以了解要使用的图像。

所以,首先,您还没有这样做,您将拥有一个具有 eventType 属性的注解:

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

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

@implementation EventAnnotation
@end

现在,在这种情况下,我将枚举用于我的事件类型,但您可以使用任何您想要的类型。 (即使你坚持使用事件类型数组,我仍然会使用枚举来删除代码中散布的神秘 0/1/2 值。)

然后,当您向地图添加注释时,请使用这种新的注释类型,而不是 MKPointAnnotation

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

现在您的所有注释都是EventAnnotation,您可以让您的viewForAnnotation 采取相应措施:

- (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;
}

【讨论】:

  • 不用说,EventTypeSmileyEventTypeDollar 是坏名字,但我只有你的图像名称。您显然会使用更有意义的枚举值名称。
  • 当我尝试你的代码时,它会返回 3 个重复的符号,用于架构 x86_64
  • 重复符号 _OBJC_CLASS_$_EventAnnotation 在:,重复符号 _OBJC_METACLASS_$_EventAnnotation 在:,重复符号 _OBJC_IVAR_$_EventAnnotation._eventType 在:
  • @AbhinandanPratap - 您的项目中已经有 EventAnnotation 类型,或者您没有正确添加此代码(不知何故添加了两次)。
  • 例如如果您不小心将@implementation 放入.h 中,您可能会遇到此类问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多