ios - MKAnnotation setImage 适用于 iPhone,但不适用于 iPad/iPhone 6+

标签 ios ipad mkmapview mkannotation mkannotationview

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

enter image description here

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

enter image description here

下面是设置标注图片的代码,以及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
  }
}

这是我的 parking_lot_icon 图像 Assets :

enter image description here

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

最佳答案

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

您不能调用 map View 的 viewForAnnotation instance 方法并在该 View 上设置 image,因为那将是一次性执行不会“坚持”到 View 。

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

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

viewForAnnotation 委托(delegate)方法的示例实现:

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

确保设置了 map View 的 delegate 属性,或者它的导出连接到 Storyboard/xib 中的 View Controller ,否则即使实现了委托(delegate)方法也不会被调用。


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

关于ios - MKAnnotation setImage 适用于 iPhone,但不适用于 iPad/iPhone 6+,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30002804/

相关文章:

iphone - iOS 中的像素化过渡

ios - 如何有效地使用 CoreData 在后台获取许多托管对象并在主线程上更新 UI?

ios - Meteor - 如何检测应用程序是否已打开?

iphone - 从通用应用程序中排除 iPhone 3GS 和旧款 iPhone 和 iPod

ios - 在 MapView 中搜索注释

iphone - 如何在 iPhone 应用程序的单个 map View 中显示多个位置

objective-c - 不同颜色的多边形叠加

ios - 从照片应用程序中选择时将 UITabBar 重新创建为 UIToolbar

ios - 单击 UIButton for Webview 加载到 ipad 后应用程序崩溃

iphone - 触摸位置的值超出 View 范围