[英]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.