我将MKPointAnnotation子类化,并添加了NSStringUIImage,以便可以将这些元素传递给MKPinAnnotationView。该字符串很好地传递到MKPinAnnotationView中,但是image属性作为null传递。我不知道为什么。我会说,一次在手机上运行此代码,图像一次出现在大头针上,所以也许我内存泄漏了?我编译图像的其他1000次在日志中显示为null,并且不显示。任何帮助表示赞赏。

这是我的子类customMapAnnotation.h:

@interface customMapAnnotation : MKPointAnnotation

@property (strong, nonatomic) NSString *restaurantID;

@property (strong, nonatomic) UIImage *restaurantIcon;

@end

这是创建我的customMapAnnotation的地方。我正在使用Parse.com,所以这里有一条语句可以将PFFile转换为UIImage。如果检查日志,则在运行时确认foodPoint.restaurantIcon具有值。
customMapAnnotation *foodPoint = [[customMapAnnotation alloc] init];
foodPoint.coordinate = spot;
foodPoint.restaurantID = [object objectId];
foodPoint.title = [object objectForKey:@"restaurantName"];
foodPoint.subtitle = [object objectForKey:@"cuisineType"];
leftIcon = [object objectForKey:@"restaurantImage"];

[leftIcon getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
    if (!error) {
        image = [UIImage imageWithData:data];

        // image can now be set on a UIImageView
        foodPoint.restaurantIcon = image;
    }
}];

[self.mainMap addAnnotation:foodPoint];

现在这是我的MKPinAnnotationView的所有代码。请注意,我运行NSLog来确认fp.restaurantIcon是否具有值,并且它为null。我知道NSLog的这种用法不太合适,但是它应该返回图像的内存位置。它返回null。同样,我的其他自定义属性fp.restaurantId运行正常。
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
    static NSString *identifier = @"RoutePinAnnotation";
    if (annotation == mapView.userLocation)
    {
        return nil;
    }
    else
    {
        MKPinAnnotationView *pinView = [[MKPinAnnotationView alloc]
                                        initWithAnnotation:annotation reuseIdentifier:identifier];
        pinView.animatesDrop=NO;
        pinView.canShowCallout=YES;

        UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];

        //cast annotation parameter to our class so compiler understands...
        customMapAnnotation *fp = (customMapAnnotation *)annotation;

        NSLog(fp.restaurantIcon);

        //get restaurantID from the annotation parameter ("fp")...
        [rightButton setTitle:fp.restaurantID forState:UIControlStateNormal];
        [rightButton addTarget:self
                        action:@selector(buttonMethod:)
              forControlEvents:UIControlEventTouchUpInside];

        pinView.rightCalloutAccessoryView = rightButton;

        //NSLog(fp.restaurantIcon);

        UIImageView *profileIconView = [[UIImageView alloc] initWithImage:fp.restaurantIcon];
        profileIconView.frame = CGRectMake(0,0,31,31);

        pinView.leftCalloutAccessoryView = profileIconView;

        return pinView;
    }
}

这是我的didSelectAnnotationView:
 - (void) mainMap:(MKMapView *)mainMap didSelectAnnotationView:(MKAnnotationView *)view
{
    if ([view.annotation isKindOfClass:[chwMapAnnotation class]])
    {
        chwMapAnnotation *fp = (chwMapAnnotation *)view.annotation;
        UIImageView *profileIconView = [[UIImageView alloc] initWithImage:fp.restaurantIcon];
        profileIconView.frame = CGRectMake(0,0,31,31);
        view.leftCalloutAccessoryView = profileIconView;
    }
}

最佳答案

我同意@Vincent的评论,因为图像是异步加载到后台的,所以在调用viewForAnnotation时还没有加载图像,因此注释的标注被留有空白的左图标。

通过getDataInBackgroundWithBlock完成图像加载后,没有自动信号告诉注释视图刷新其leftCalloutAccessoryView

在这种情况下,一种粗略的解决方法是在选择注释时(即在显示包含leftCalloutAccessoryView的标注时)手动强制刷新leftCalloutAccessoryView

选择注释后, map 视图将调用didSelectAnnotationView委托方法。在这里,可以应用粗略的解决方法:

-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    if ([view.annotation isKindOfClass:[customMapAnnotation class]])
    {
        customMapAnnotation *fp = (customMapAnnotation *)view.annotation;
        UIImageView *profileIconView = [[UIImageView alloc] initWithImage:fp.restaurantIcon];
        profileIconView.frame = CGRectMake(0,0,31,31);
        view.leftCalloutAccessoryView = profileIconView;
    }
}

当然,可能还没有为所选的注释加载图像(可能只是花费了很长时间,或者图像的URL无效,等等)。

您可以在viewForAnnotation中进行操作,如果fp.restaurantIconnil,则将左侧图标设置为添加到项目资源中的某个通用“正在加载”图标。在didSelectAnnotationView中,您还可以首先检查fp.restaurantIcon是否仍为nil,如果是,则什么也不做(即,将图标保留为通用的“正在加载”图标)。

不太简单的解决方案是创建一个自定义注释视图类,该类从其关联的注释中侦听“图像已完成加载”消息,并自动刷新自身。

08-26 04:51