MKAnnotation setImage 适用于 iPhone,但不适用于 iPad/iPhone 6+
MKAnnotation setImage works on iPhone, but not iPad/iPhone 6+
我正在尝试为我的 MKMapView 中的 MKPointAnnotation 设置自定义图像。除了 6+:
以外,所有 iPhone 的图像都正确设置
但在 iPhone 6+ 和 iPad 上,注释使用默认图钉而不是我的图片:
下面是设置注释图像的代码,以及Images.xcassets中parking_spot_icon.png的入口。 None 我的代码取决于设备的大小,并且没有相关的错误或构建警告(特别是,没有关于不正确的图像大小的警告)。
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) [=13=] = {
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 图片资产:
我能看到的唯一区别是 iPad 使用了不同的图像比例;但我包含了所有比例的图标。我觉得我错过了一些明显的东西。谁能想到为什么我的图像可以设置为 iPhone 而不是 iPad/6+ 的原因?
要为注释视图设置自定义图像,您必须实现 viewForAnnotation
delegate 方法。
您不能调用地图视图的 viewForAnnotation
instance 方法并在该视图上设置 image
因为那将是一次性执行不是 "stick" 到视图。
当地图视图稍后需要此或其他注释的视图时(这可能在添加注释后很长时间),它将调用委托方法(如果已实现)。如果未实现委托方法,地图视图会为您显示默认的红色图钉。
它 "works" 在 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
属性 已设置或它的出口已连接到 storyboard/xib 中的视图控制器,否则委托方法将不会被调用,即使它是已实施。
您还应该在创建注释时删除对 selectAnnotation
和 deselectAnnotation
的调用——它们不是必需的。
我正在尝试为我的 MKMapView 中的 MKPointAnnotation 设置自定义图像。除了 6+:
以外,所有 iPhone 的图像都正确设置但在 iPhone 6+ 和 iPad 上,注释使用默认图钉而不是我的图片:
下面是设置注释图像的代码,以及Images.xcassets中parking_spot_icon.png的入口。 None 我的代码取决于设备的大小,并且没有相关的错误或构建警告(特别是,没有关于不正确的图像大小的警告)。
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) [=13=] = {
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 图片资产:
我能看到的唯一区别是 iPad 使用了不同的图像比例;但我包含了所有比例的图标。我觉得我错过了一些明显的东西。谁能想到为什么我的图像可以设置为 iPhone 而不是 iPad/6+ 的原因?
要为注释视图设置自定义图像,您必须实现 viewForAnnotation
delegate 方法。
您不能调用地图视图的 viewForAnnotation
instance 方法并在该视图上设置 image
因为那将是一次性执行不是 "stick" 到视图。
当地图视图稍后需要此或其他注释的视图时(这可能在添加注释后很长时间),它将调用委托方法(如果已实现)。如果未实现委托方法,地图视图会为您显示默认的红色图钉。
它 "works" 在 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
属性 已设置或它的出口已连接到 storyboard/xib 中的视图控制器,否则委托方法将不会被调用,即使它是已实施。
您还应该在创建注释时删除对
selectAnnotation
和 deselectAnnotation
的调用——它们不是必需的。