简体   繁体   English

无法使用plist文件获取其他图钉图像

[英]Can't get different pin image using plist file

I use plist file to store annotation data that have Name, Address, Coordinates and Icon (pin image name) strings in dictionary. 我使用plist文件存储在词典中具有名称,地址,坐标和图标(固定图像名称)字符串的注释数据。 I need to show my annotations on map with pin image depending on Icon string in plist. 我需要根据plist中的图标字符串在地图上用大头针图像显示我的注释。 I loop my annotation dictionaries but it show on map pin image from first dict on all my pins. 我循环了注解字典,但从我的所有图钉上的第一个字典开始,它就显示在地图图钉图像上。

My code: 我的代码:

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


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

    static NSString* AnnotationIdentifier = @"AnnotationIdentifier";
    MKPinAnnotationView* pinView = [[MKPinAnnotationView alloc]
                                    initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];


    NSString *path = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"plist"];
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];

    for(path in dict){

        NSString *theCategory;

        theCategory = [NSString stringWithFormat:@"%@", path];
        NSLog(@"%@", path);

        NSArray *anns = [dict objectForKey:theCategory];

        pinView.image = [UIImage imageNamed:[[anns objectAtIndex:0] objectForKey:@"Icon"]];

    }

    pinView.canShowCallout=YES;


    return pinView;
}

My plist file construction: 我的plist文件构造:

在此处输入图片说明

What it show to me: 它显示给我的是:

在此处输入图片说明

The viewForAnnotation delegate method will get called for each annotation added. 将为添加的每个注释调用viewForAnnotation委托方法。

The for-loop you have inside that method will run the same way for each annotation. 该方法中的for循环将对每个注释以相同的方式运行。 All the for-loop ends up doing (every time for each annotation) is setting pinView.image to the last item read by the for-loop. 所有的for循环最终都会完成(每次为每个注释添加)将pinView.image设置pinView.image for循环读取的最后一项。 This happens to be the first item in the first dictionary in the plist. 这恰好是plist中第一个词典中的第一项。

You need to instead set pinView.image to the Icon of the item that is for the current annotation that viewForAnnotation is being called for (ie. the annotation parameter that is passed). 您需要将pinView.image设置为要为其viewForAnnotation当前注释(即,传递的annotation参数)的项目的Icon So you could keep the for-loop and check if the item matches annotation and only then set pinView.image (and then break out of the for-loop). 所以,你可以保持对环和检查项匹配annotation ,然后才设置pinView.image (然后break了的for循环)。

But it's not a good idea to constantly be re-reading and looping through a plist in that delegate method. 但是,不断地重新读取和遍历该委托方法中的plist并不是一个好主意。 It's better to make Icon a property of your annotation class, set the property when creating the annotation (you are probably looping through the plist to create the annotations in the first place), and then just use that property directly from the annotation object itself in the viewForAnnotation delegate method. 最好将Icon 设置为注释类的属性,在创建注释时设置属性 (您可能首先遍历plist来创建注释),然后直接在注释对象本身中使用该属性viewForAnnotation委托方法。

Assuming you have some custom annotation class, add Icon as a property: 假设您有一些自定义注释类,请将Icon添加为属性:

@interface MyAnnotationClass : NSObject<MKAnnotation>

@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;
@property (nonatomic, copy) NSString *icon;  //<---and @synthesize it in .m

Then in the place where you loop through the plist to create the annotations, set the icon property just like you are setting the title property: 然后在您遍历plist来创建注释的地方,像设置title属性一样设置icon属性:

ann.title = [item objectForKey:@"Name"];
ann.icon = [item objectForKey:@"Icon"];

Finally, in viewForAnnotation , you can read the icon property directly from the annotation . 最后,在viewForAnnotation ,您可以直接从annotation读取icon属性。 But first, you should check that annotation is of your custom class type (so the user location blue dot is not affected and to be reasonably sure annotation will have the property you're about to access): 但是首先,您应该检查annotation是否属于您的自定义类类型(这样用户位置的蓝点不会受到影响,并且可以合理地确定annotation将具有您将要访问的属性):

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if (![annotation isKindOfClass:[MyAnnotationClass class]])
    {
        // Note "!" sign in front of above condition.
        // Return nil (default view) if annotation is 
        // anything but your custom class.
        return nil;
    }

    static NSString* AnnotationIdentifier = @"AnnotationIdentifier";

    MKAnnotationView *pinView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
    // Create an MKAnnotationView instead of MKPinAnnotationView
    // because we are setting a custom image.
    // Using MKPinAnnotationView sometimes overrides custom image
    // with the built-in pin view.
    if (pinView == nil)
    {
        pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
        pinView.canShowCallout = YES;
    }
    else
        pinView.annotation = annotation;

    MyAnnotationClass *myAnn = (MyAnnotationClass *)annotation;
    pinView.image = [UIImage imageNamed:myAnn.icon];
    // May want to check if myAnn.icon is blank (length == 0)
    // (OR if pinView.image is still nil after setting)
    // and show some default image in that case otherwise
    // annotation will be invisible.

    return pinView;
}

By the way, in your plist file, Test3 has no Icon setting. 顺便说一句,在您的plist文件中, Test3没有Icon设置。

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

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