无法将UIImage传递给MKPinAnnotationView [英] Having trouble passing UIImage to MKPinAnnotationView

查看:61
本文介绍了无法将UIImage传递给MKPinAnnotationView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我继承了MKPointAnnotation的子类,并添加了NSStringUIImage,因此我可以将这些元素传递给MKPinAnnotationView.字符串传递到MKPinAnnotationView细处,但是image属性以null的形式通过.我不知道为什么.我会说,一次在手机上运行此代码,图像一次出现在大头针上,所以也许我内存泄漏了吗?我编译图像的其他1000次在日志中显示为null,并且不显示.感谢您的帮助.

I subclassed MKPointAnnotation and added a NSString and a UIImage so I can pass these elements to an MKPinAnnotationView. The string passes into the MKPinAnnotationView fine, but the image attribute is coming through as null. I can't figure out why. I will say that one time running this code on my phone the image appeared on a pin once, so maybe I have a memory leak? The other 1000 times I've compiled the images show as null in the log and do not appear. Any help is appreciated.

这是我的子类customMapAnnotation.h:

Here is my subclass customMapAnnotation.h:

@interface customMapAnnotation : MKPointAnnotation

@property (strong, nonatomic) NSString *restaurantID;

@property (strong, nonatomic) UIImage *restaurantIcon;

@end

在这里创建我的customMapAnnotation.我正在使用Parse.com,所以这里有一条语句可以将PFFile转换为UIImage.如果检查日志,则在运行时确认foodPoint.restaurantIcon具有值.

Here is where my customMapAnnotation is created. I'm using Parse.com so there is a statement here to convert a PFFile to a UIImage. If I check the log I confirm that foodPoint.restaurantIcon has a value when this is ran.

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的这种用法不是很好,但是它应该返回图像的内存位置.它返回空值.同样,我的其他自定义属性fp.restaurantId正常工作.

Now here is all of my code for my MKPinAnnotationView. Notice I run an NSLog to confirm if fp.restaurantIcon has a value, and it is null. I know this use of NSLog is not graceful, but it should return the memory location of the image. It comes back null. Again, my other custom attribute fp.restaurantId is working fine.

- (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时还没有加载它们,并且因此注释的标注被留有一个空白的左侧图标.

I agree with the comment by @Vincent that since the images are being loaded in the background asynchronously, they have not yet been loaded when viewForAnnotation is called and so the annotation's callout is stuck with a blank left icon.

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

When the image loading is finished by getDataInBackgroundWithBlock, there is no automated signal telling the annotation view to refresh its leftCalloutAccessoryView.

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

A crude workaround in this case would be to manually force the refresh of the leftCalloutAccessoryView when the annotation is selected (which is when the callout will be displayed containing the leftCalloutAccessoryView).

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

When an annotation is selected, the map view calls the didSelectAnnotationView delegate method. Here, the crude workaround can be applied:

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

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

Of course, it's possible that the image still hasn't loaded for the annotation that was selected (it's either just taking very long or the image url is invalid, etc).

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

What you can do is in viewForAnnotation, if fp.restaurantIcon is nil, set the left icon to some generic "loading" icon that you add to the project resources. In didSelectAnnotationView, you can also first check if fp.restaurantIcon is still nil and, if so, do nothing (ie. leave the icon as the generic "loading" icon).

一种不太粗略的解决方案可能是创建一个自定义注释视图类,该类从其关联的注释中侦听图像加载完成"消息并自动刷新.

A less crude solution might be to create a custom annotation view class that listens for an "image finished loading" message from its associated annotation and refreshes itself automatically.

这篇关于无法将UIImage传递给MKPinAnnotationView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆