【问题标题】:MKAnnotation setImage works on iPhone, but not iPad/iPhone 6+MKAnnotation setImage 适用于 iPhone,但不适用于 iPad/iPhone 6+
【发布时间】:2015-05-02 13:23:27
【问题描述】:

我正在尝试在我的 MKMapView 中为 MKPointAnnotation 设置自定义图像。除了 6+ 以外,所有 iPhone 上的图像都设置正确:

但在 iPhone 6+ 和 iPad 上,注释有默认 pin 而不是我的图片:

下面是设置注解图片的代码,以及Images.xcassets中parking_spot_icon.png的入口。我的代码都不依赖于设备的大小,并且没有相关的错误或构建警告(特别是没有关于不正确图像大小的警告)。

MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = parkingLot->coordinate;
[_mapView addAnnotation:annotation];
[_mapView selectAnnotation:annotation animated:YES]; // this is needed for the image to be set correctly on iphone.
[_mapView deselectAnnotation:annotation animated:YES]; // this is needed for the image to be set correctly on iphone.
        annotation.title = parkingLot->name;
UIImage *image = [UIImage imageNamed:@"parking_spot_icon.png"];
[[_mapView viewForAnnotation:annotation] setImage:image];

我尝试单步执行代码,我看到 UIImage *image 在两种情况下(iPhone 和 iPad)都打印为以下对象:

(lldb) p *image
(UIImage) $0 = {
  NSObject = {
    isa = UIImage
  }
   _imageRef = 0x00007fd2d733fd30 // differs run-to-run
  _scale = 3 // 2 on iPhone, 3 on iPad
  _imageFlags = {
    named = 1
    imageOrientation = 0
    cached = 0
    hasPattern = 0
    isCIImage = 0
    renderingMode = 0
    suppressesAccessibilityHairlineThickening = 0
    hasDecompressionInfo = 0
  }
}

这是我的 park_lot_icon 图像资源:

我能看到的唯一区别是 iPad 使用了不同的图像比例;但我包括了所有尺度的图标。我觉得我错过了一些明显的东西。谁能想到为什么我的图像可以设置在 iPhone 上而不是 iPad/6+ 上?

【问题讨论】:

  • 你添加了@3x 图片吗?
  • 感谢 Ashish,我确实在我的资产中添加了所有 3 个比例图像。 i.imgur.com/DesHVXB.png
  • 你是否实现了viewForAnnotation delegate 方法并且你在那里创建了一个MKAnnotationView?直接调用viewForAnnotation并按照问题中的代码设置图像不是这样做的方法。
  • 感谢 Anna,将我的 setImage 放入 viewForAnnotation 工作!现在我在所有设备上都有自定义注释。

标签: ios ipad mkmapview mkannotation mkannotationview


【解决方案1】:

要为注释视图设置自定义图像,您必须实现viewForAnnotation delegate 方法。

您不能调用地图视图的viewForAnnotation instance 方法并在该视图上设置image,因为这将是一次性执行,不会“粘”在视图上。

当地图视图稍后需要此注释或其他注释的视图时(这可能在添加注释后很长时间),它将调用委托方法(如果已实现)。如果未实现委托方法,则地图视图会为您显示默认的红色图钉。

它在 iPhone 而不是 iPad 上“工作”的事实只是随机的、不可预测的行为,您不应该依赖它。

viewForAnnotation 委托方法的示例实现:

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        //if this is the user location, return nil so map view
        //draws default blue dot for it...
        return nil;
    }

    static NSString *reuseId = @"ann";

    MKAnnotationView *av = [mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
    if (av == nil) {
        av = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
        av.canShowCallout = YES;
        UIImage *image = [UIImage imageNamed:@"parking_spot_icon.png"];
        av.image = image;
    }
    else {
        //we are recycling a view previously used for another annotation,
        //update its annotation reference to the current one...
        av.annotation = annotation;
    }

    return av;
}

确保地图视图的delegate 属性已设置,或者其出口已连接到情节提要/xib 中的视图控制器,否则即使已实现委托方法也不会被调用。


您还应该在创建注释时删除对selectAnnotationdeselectAnnotation 的调用——它们不是必需的。

【讨论】:

  • 非常感谢您的更新,它还回答了我的下一个问题,即“如何更改除用户位置之外的所有注释?”
  • 嗨,M 遇到同样的问题,它适用于视网膜设备上的 (@2x) 图像,但对于 6+ 我需要 (@3x) 图像,它不适用于 6+。有什么帮助吗?
  • 如果您知道此类问题,请检查一下。 stackoverflow.com/questions/30476231/…
猜你喜欢
  • 2011-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-16
  • 1970-01-01
  • 2016-02-05
相关资源
最近更新 更多