MKMapView自定义图像不起作用

时间:2012-08-22 21:16:00

标签: iphone objective-c ios mkmapview

尝试遵循本教程:http://www.switchonthecode.com/tutorials/building-an-earthquake-monitor-for-iphone-using-mapkit

我的图标显示在所有正确的位置(和正确的数字)&图像也显示出来。 (但它始终是相同的图像。这是因为条件if(self.marker.type ==“nzpost”不起作用,因为type始终为null(与initWithAnnotation()中标记对象的所有属性一样)由于某种原因,这些属性都是空的。

注释视图界面:

@interface PayMarkerAnnotationView : MKAnnotationView {
    PaymentMarker *marker;
}

@property (strong, nonatomic) IBOutlet PaymentMarker *marker;

@end

初始化注释:(这里是self.marker.type应该有一个值。

- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
    if(self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {
        self.backgroundColor = [UIColor clearColor];
        NSString* imageName = [[NSString alloc] init];

        if([self.marker.type isEqualToString:@"nzpost"]) {
            imageName = @"icon-map-post.png";
        } else {
            imageName = @"icon-map-incharge.png";
        }
        self.image = [UIImage imageNamed:imageName];
    }
    return self;
}

MapView的:

- (MKAnnotationView *)mapView:(MKMapView *)lmapView viewForAnnotation:(id <MKAnnotation>)annotation {
    PayMarkerAnnotationView *markerView = (PayMarkerAnnotationView *)[lmapView dequeueReusableAnnotationViewWithIdentifier:@"markerView"];
    if(markerView == nil) {
        markerView = [[PayMarkerAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"markerView"];
    }
    markerView.annotation = annotation;
    return markerView;
}

中添加我的标记
-(void)renderPaymentMarkers
{
    [self.map addAnnotations: nzPostMarkers];
    [self.map addAnnotations: inChargeMarkers];
}

Marker class:

@interface PaymentMarker : NSObject <MKAnnotation> {
    NSString* type;
    NSString* description;
    float latitude;
    float longitude;}

@property (nonatomic) NSString* description;
@property (nonatomic) NSString* type;
@property (nonatomic) float latitude;
@property (nonatomic) float longitude;

//MKAnnotation
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;

@end

1 个答案:

答案 0 :(得分:1)

marker中的PayMarkerAnnotationView变量永远不会设置。

(我不确定为什么你的财产也是IBOutlet。)

在访问它之前,需要在initWithAnnotation方法中进行设置:

if (self = [super initWithAnnotation...
    //set marker equal to the annotation this view is being created for...
    marker = annotation;

    self.backgroundColor = [UIColor clearColor];
    ...

但是,您首先不需要marker变量 MKAnnotationView已经有一个annotation属性,在您调用super initWithAnnotation时会设置该属性。

所以在你的initWithAnnotation中,而不是这个:

if([self.marker.type isEqualToString:@"nzpost"]) {

你可以这样做:

PaymentMarker *pm = (PaymentMarker *)self.annotation;
if([pm.type isEqualToString:@"nzpost"]) {

这应该解决主要问题。


另一个潜在的问题是,在viewForAnnotation中,如果正在从另一个注释重新使用视图,则直接更新视图的annotation属性。

这很好(虽然它应该在else块中完成),但问题是当image更新时,视图的annotation也不会更新。

因此,如果使用该视图的先前注释的类型为“nzpost”,但当前注释属于其他类型,则视图仍将显示上一个注释类型的图像。

要解决此问题,以下是两种可能的解决方案:

  • 为每种类型使用单独的reuseIdentifier(因此有两个ID:“post”和“incharge”)。这样,只有具有匹配图像的视图才会被重新用于当前注释。
  • 覆盖setAnnotation:中的PayMarkerAnnotationView并更新annotationimage属性。我更喜欢这个解决方案。


其他一些完全无关的项目......

这一行:

NSString* imageName = [[NSString alloc] init];

没有意义,因为稍后的代码会用新值覆盖imageName。所以分配的内存被放弃了。相反,只需声明imageName

NSString* imageName;

这些属性:

@property (nonatomic) NSString* description;
@property (nonatomic) NSString* type;
应该用copy属性声明

(编译器应该抱怨这个):

@property (nonatomic, copy) NSString* description;
@property (nonatomic, copy) NSString* type;

您可能还想更改description属性的名称,因为您要覆盖NSObject提供的同名属性(除非您的意图)。