我将 MKPointAnnotation
子类化并添加了一个 NSString
和一个 UIImage
这样我就可以将这些元素传递给 MKPinAnnotationView
.字符串传递到 MKPinAnnotationView
正常,但图像属性作为 null 通过。我不知道为什么。我要说的是,有一次在我的手机上运行这段代码时,图像出现在一个 pin 上,所以也许我有内存泄漏?另外 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
是否有一个值,并且它是空的。我知道 NSLog
的这种用法并不优雅,但它应该返回图像的内存位置。它返回空值。同样,我的其他自定义属性 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
完成时,没有自动信号告诉注释 View 刷新其 leftCalloutAccessoryView
。
在这种情况下,粗略 解决方法是在选择注释时手动强制刷新 leftCalloutAccessoryView
(即显示包含 leftCalloutAccessoryView
).
当注释被选中时, map View 调用didSelectAnnotationView
委托(delegate)方法。在这里,可以应用粗略的解决方法:
-(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.restaurantIcon
是 nil
,将左边的图标设置为一些通用的“加载”图标您添加到项目资源。在 didSelectAnnotationView
中,您还可以首先检查 fp.restaurantIcon
是否仍为 nil
,如果是,则什么都不做(即,将图标保留为通用的“正在加载”图标)。
一个不太粗暴的解决方案可能是创建一个自定义注释 View 类,该类从其关联的注释中监听“图像已完成加载”消息并自动刷新。
关于ios - 将 UIImage 传递给 MKPinAnnotationView 时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20875278/