Reputation: 1477
I have a mapview hundreds of annotations. I load annotations in background, and when all annotations are loaded, I call the method: setAnnotations.
I have 6 types of annotations with different pin for each other.
It works well for the first loading. But if I want to refresh the map (because I use a filter), the pin image change.
I saw a similar issue Here, but it seems not working for me.
Here my viewForAnnotation method:
//...
else if ([annotation isKindOfClass:[CustomAnnotation class]]) {
CustomAnnotation *singleAnnotation = (CustomAnnotation *)annotation;
annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"singleAnnotationView"];
if (!annotationView) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:singleAnnotation reuseIdentifier:@"singleAnnotationView"];
annotationView.canShowCallout = YES;
annotationView.centerOffset = CGPointMake(0, -20);
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
else
annotationView.annotation = annotation;
// Solution, put it here:
annotationView.image = [UIImage imageNamed:[NSString stringWithFormat:@"pin_%d", singleAnnotation.idType]];
}
//...
And here my method I call to load and reload the map:
- (void)loadMapView
{
UIActivityIndicatorView *a = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
self.mapview.hidden = YES;
a.center = CGPointMake(160, 240);
[self.view addSubview:a];
[a startAnimating];
NSMutableArray *array = [NSMutableArray new];
if(self.mapview.annotations.count > 0){
[self.mapview removeAnnotations:self.mapview.annotations];
[self.mapview removeOverlays:self.mapview.overlays];
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
for(MapObjects *obj in [MapRepository shared].repository){
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(obj.coord_geo_latitude,obj.coord_geo_longitude);
CustomAnnotation *annotation = [[CustomAnnotation alloc] initWithCoordinates:coordinate
placeName:obj.placeName
description:obj.description
idType:obj.idType];
if(annotation.coordinate.latitude != 0 || annotation.coordinate.longitude != 0)
[array addObject:annotation];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.mapview addAnnotations:array];
[self.mapview zoomToFitMapAnnotations:self.mapview];
[a stopAnimating];
self.mapview.hidden = NO;
});
});
}
What I'm doing wrong ?
Any suggestions and help are appreciate. Thank you in advance ;)
Upvotes: 2
Views: 1674
Reputation: 13860
You using reusability so (similar like in tableView rows) your images for 1..12..24.. and next will be the same. If you want to customize the images you have to insert your code outside reusability if
.
I mean this line shouldn't be in if (!annotationView)
annotationView.image = [UIImage imageNamed:[NSString stringWithFormat:@"pin_%d", singleAnnotation.idType]];
Upvotes: 1
Reputation: 19071
The problem is that the map view will re-use pins with the same reuse identifier. This is how you’re creating the pins:
annotationView = [[MKAnnotationView alloc] initWithAnnotation:singleAnnotation
reuseIdentifier:@"singleAnnotationView"];
Subsequently, you set the image. There are two potential solutions:
Here’s what #2 would look like:
CustomAnnotation *singleAnnotation = (CustomAnnotation *)annotation;
annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"singleAnnotationView"];
if (!annotationView) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:singleAnnotation reuseIdentifier:@"singleAnnotationView"];
annotationView.canShowCallout = YES;
annotationView.centerOffset = CGPointMake(0, -20);
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
else {
annotationView.annotation = annotation;
}
annotationView.image = [UIImage imageNamed:[NSString stringWithFormat:@"pin_%d", singleAnnotation.idType]];
Upvotes: 9