简体   繁体   English

MKMapview注释缩放后动态图钉图像更改

[英]MKMapview annotation dynamic pin image changes after zooming

I am working on a little project that shows 7 different types of annotations on the map. 我正在做一个小项目,在地图上显示7种不同类型的注释。 My annotations are taken from a url result in array and I parse it using JSON. 我的注释来自数组中的url结果,我使用JSON对其进行了解析。 I have lots of annotations and everything seems to look good once the map loads. 我有很多注释,一旦地图加载,一切看起来都不错。 After zooming in and zooming out, the the pin images changes for some reason to the wrong pin image (a specific image, no clue why). 放大和缩小后,针脚图像由于某种原因变为错误的针脚图像(特定图像,不知道为什么)。

I am sure I am missing something here...may you please help :) ? 我确定我在这里缺少什么...可以请您帮忙:)吗?

Here's one part of my code, let me know if you need anymore of it: 这是我的代码的一部分,如果您需要它,请告诉我:

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{

static NSString *identifier;

if(_mapView.tag==1){identifier = @"TurbulencePin";}
if(_mapView.tag==2){identifier = @"IcingPin";}
if(_mapView.tag==3){identifier = @"WindsPin";}
if(_mapView.tag==4){identifier = @"TemperaturePin";}
if(_mapView.tag==5){identifier = @"CloudsPin";}
if(_mapView.tag==6){identifier = @"VisibilityPin";}
if(_mapView.tag==7){identifier = @"MultiplePin";}


if ([annotation isKindOfClass:[MKUserLocation class]])
    return nil;

if ([annotation isKindOfClass:[Annotation class]]) {

    CustomAnnotationView* annotationView = (CustomAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
    annotationView = nil;

    if (annotationView == nil) {

        annotationView = [[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;


        UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:@"%@.png",identifier]];
        annotationView.image = img;

    }
else
    {

        annotationView.annotation = annotation;

    }


    return annotationView;

}
return nil;

}

Update: 更新:

Based upon feedback of others, I've modified the code for the image setting to be as follows: 根据其他人的反馈,我将图像设置的代码修改如下:

 Annotation *myCustomAnn = (Annotation *)annotation;
 NSString *imgName = myCustomAnn.imageName;
 UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:@"%@Pin.png",imgName]];
 annotationView.image = img;

 return annotationView;

Plus, I removed the annotationView = nil; 另外,我删除了annotationView = nil;

However, I cannot set the image name in the annotation.m as a hardcoded value because I need to display a different pin image for each annotation. 但是,我无法将注释.m中的图像名称设置为硬编码值,因为我需要为每个注释显示不同的图钉图像。 I'm sure that there is an explanation but the only value that I can get from the annotation.m under the mapView:viewForAnnotation: is the annotation coordinates ( myCustomAnn.coordinate.latitude and myCustomAnn.coordinate.longitude) , I have no clue how to get other properties from the annotation.m 我敢肯定有一个解释,但是从mapView:viewForAnnotation:下的commentment.m可以得到的唯一值是注释坐标( myCustomAnn.coordinate.latitudemyCustomAnn.coordinate.longitude) ,我不知道如何从annotation.m获取其他属性

The other properties, such as title, imgname etc comes back as null 其他属性(例如title,imgname等)返回为null

The main problem is that the code in viewForAnnotation is relying on the outside variable _mapView.tag to determine the annotation view. 主要问题是viewForAnnotation中的代码依赖于外部变量_mapView.tag来确定注释视图。

It is unsafe to assume when and how frequently the viewForAnnotation delegate method will be called by the map. 假设地图将在何时以及以何种频率viewForAnnotation委托方法是不安全的。

If an annotation's view depends on certain values, it is generally best to embed those values directly in the annotation object itself. 如果注释的视图取决于某些值,通常最好将这些值直接嵌入到注释对象本身中。 This way, in the viewForAnnotation delegate method, you can reference those annotation-specific values through the annotation parameter that is passed to the method. 这样,在viewForAnnotation委托方法中,您可以通过传递给方法的annotation参数来引用那些特定于annotation值。 Those annotation-specific values should be set when creating the annotation (before calling addAnnotation ). 在创建注释时(在调用addAnnotation之前)应设置那些特定于注释的值。

For some more details and examples, see: 有关更多详细信息和示例,请参见:

A separate issue is the code is setting annotationView to nil after calling dequeueReusableAnnotationViewWithIdentifier which defeats the dequeue. 一个单独的问题是代码在调用dequeueReusableAnnotationViewWithIdentifier来取消出dequeueReusableAnnotationViewWithIdentifier后,将annotationView dequeueReusableAnnotationViewWithIdentifier设置为nil


At least in viewForAnnotation , the corrected code where it handles the Annotation class might look like this (not the whole method -- just the part inside the second if ): 至少在viewForAnnotation ,处理Annotation类的更正后的代码可能看起来像这样(不是整个方法,而是第二个if的部分):

static NSString *identifier = @"ann";

CustomAnnotationView* annotationView = (CustomAnnotationView*)[mapView 
    dequeueReusableAnnotationViewWithIdentifier:identifier];

//annotationView = nil;  // <-- remove this line

if (annotationView == nil) 
{
    annotationView = [[CustomAnnotationView alloc] 
                         initWithAnnotation:annotation 
                         reuseIdentifier:identifier];
    annotationView.enabled = YES;
    annotationView.canShowCallout = YES;
}
else
{
    annotationView.annotation = annotation;
}

//MOVE the setting of the image to AFTER the dequeue/create 
//because the image property of the annotation view 
//is based on the annotation and we can update image in one place
//after both the dequeue and create are done...

//Get the image name from the annotation ITSELF 
//from a custom property (that you add/set)
Annotation *myCustomAnn = (Annotation *)annotation;

NSString *imgName = myCustomAnn.imageName;  
//imageName is the custom property you added/set

UIImage *img = [UIImage imageNamed:
                   [NSString stringWithFormat:@"%@.png",imgName]];

annotationView.image = img;

return annotationView;

SOLVED by Rob 由Rob解决

The problem was, that I could not retrive the annotation properties which I set at my VC. 问题是,我无法检索在VC中设置的注释属性。 The reason was that I used the [_mapView addAnnotation:ann]; 原因是我使用了[_mapView addAnnotation:ann]; command, before I set all the annotation's properties. 命令,然后设置所有注释的属性。 That said, by moving this line to the end part of the annotation initial properties setup, solved the problem. 就是说,通过将这条线移动到注释初始属性设置的末尾,可以解决该问题。

Thank you all and big thanks to Rob! 谢谢大家,非常感谢Rob! I'm up to my next challenge. 我要迎接下一个挑战。

One issue is that the viewForAnnotation is determining the correct image to show based upon a class instance variable. 一个问题是viewForAnnotation根据类实例变量确定要显示的正确图像。 Generally the identifier for the annotation's image would be a property of the custom annotation itself, not some external instance variable. 通常,注释图像的标识符将是自定义注释本身的属性,而不是某些外部实例变量。

On top of that, it appeared that the annotation was being added to the map before all of the annotation's properties were being set. 最重要的是,似乎在设置所有注释的属性之前,已将注释添加到地图。 One should defer the addAnnotation until all of the annotation's properties are set. 应该将addAnnotation推迟到所有注释的属性都设置好之后。

Alternatively, you can add the annotations to a NSMutableArray , tweak them as you see fit, and only add the annotations at the very end using the addAnnotations (note the s), passing it the array. 或者,您可以将注释添加到NSMutableArray ,根据需要进行调整,然后仅使用addAnnotations (请注意s)在最后添加注释,并将其传递给数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM