无法将UIImage传递给MKPinAnnotationView
我subclassed MKPointAnnotation
并添加一个NSString
和一个UIImage
所以我可以将这些元素传递给一个MKPinAnnotationView
。 该string传递到MKPinAnnotationView
罚款,但图像属性是通过为空。 我无法弄清楚为什么。 我会说有一次在我的手机上运行这个代码的图像出现在一个针一次,所以也许我有一个内存泄漏? 其他1000次我编译的图像在日志中显示为空,并没有出现。 任何帮助表示赞赏。
这是我的子类customMapAnnotation.h:
@interface customMapAnnotation : MKPointAnnotation @property (strong, nonatomic) NSString *restaurantID; @property (strong, nonatomic) UIImage *restaurantIcon; @end
这是我的customMapAnnotation
创build的地方。 我正在使用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
不是优雅的,但它应该返回图像的内存位置。 它返回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的评论,因为图像被asynchronous加载到背景中,所以当viewForAnnotation
被调用时,它们还没有加载,所以注解的标注卡住了一个空白的左侧图标。
当图像加载通过getDataInBackgroundWithBlock
完成时,没有自动的信号告诉注解视图来刷新其leftCalloutAccessoryView
视图。
在这种情况下,一个粗略的解决方法是手动强制刷新leftCalloutAccessoryView
当注释被选中时(即显示包含leftCalloutAccessoryView
的标注)。
选中注释后,地图视图将调用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; } }
当然,图片仍然没有加载所select的注释(可能只是很长或图片url无效等)。
你可以做什么是在viewForAnnotation
,如果fp.restaurantIcon
是nil
,左侧的图标设置为一个通用的“加载”图标,你添加到项目资源。 在didSelectAnnotationView
,您也可以先检查fp.restaurantIcon
是否仍然nil
,如果是,则不做任何事情( fp.restaurantIcon
图标保留为通用的“加载”图标)。
一个不太粗糙的解决scheme可能是创build一个自定义的注释视图类,它从相关注释中侦听“图像完成加载”消息并自动刷新。
我会说不要试图inheritanceMKPointAnnotation,创build自己的符合MKAnnotation协议的对象,并使用不是MKPinAnnotationViews的注解视图。