Force MKMapView viewForAnnotation para actualizar

Así que tengo un MKMapView con todos los pines agregados, y el color del pin depende de si se establece un valor para ese pin. La primera vez que carga la aplicación, se llama a viewForAnnotation y los colors se configuran en consecuencia. Sin embargo, cuando actualizo los detalles del pin (como la location, el título, etc.) también actualizo pinColour para encontrar que no se actualiza. Parece que viewForAnnotation no se vuelve a llamar después del agregado inicial.

He leído muchas preguntas similares a esto y puedo confirmar que mapView.delegate = self;

Aquí está mi código viewForAnnotation :

 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(MapAnnotation *)annotation { if([annotation class] == MKUserLocation.class) return nil; NSString *pinIdentifier = annotation.identifier; // This is a unique string for each pin and is getting populated every time! MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:pinIdentifier]; if(annotationView == nil) annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinIdentifier]; else annotationView.annotation = annotation; // Never had this line fire... annotationView.canShowCallout = YES; annotationView.animatesDrop = NO; annotationView.enabled = YES; annotationView.tag = annotation.counter; if(annotation.pinColour == Stopped) // from enum annotationView.pinColor = MKPinAnnotationColorRed; else annotationView.pinColor = MKPinAnnotationColorGreen; UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; [infoButton addTarget:self action:@selector(mapCalloutButtonPressed:) forControlEvents:UIControlEventTouchUpInside]; infoButton.tag = annotation.counter; annotationView.rightCalloutAccessoryView = infoButton; return annotationView; } 

Aquí está el código donde agrego el pin:

 CLLocationCoordinate2D annotationCoord; annotationCoord.latitude = latestPosition.latitude; annotationCoord.longitude = latestPosition.longitude; MapAnnotation *annotation = [[MapAnnotation alloc] init]; annotation.coordinate = annotationCoord; annotation.identifier = theIdentifier; annotation.title = theTitle; annotation.subtitle = theSubtitle annotation.pinColour = [self getPinColour]; annotation.counter = theCounter; [theMapView addAnnotation:annotation]; 

Aquí está el código donde actualizo el pin (método diferente para agregar):

 updatePin = true; pinCounter = mapPin.counter; CLLocationCoordinate2D annotationCoord; annotationCoord.latitude = latestPosition.latitude; annotationCoord.longitude = latestPosition.longitude; [mapPin setCoordinate:annotationCoord]; mapPin.identifier = theIdentifier; mapPin.subtitle = theSubtitle; mapPin.pinColour = [self getPinColour]; 

No estoy seguro de lo que me estoy perdiendo. viewForAnnotation obviamente está funcionando, ¡simplemente no se llama después del agregado inicial! Si fuera a llamar a esta function, estoy 100% seguro de que funcionaría, ya que cambia de color si reinicio la aplicación.

EDIT: Oh, y realmente no quiero comenzar a eliminar las annotations y volver a agregarlas. ¡Es lo que estoy haciendo en el corto ploop de todos modos!

Debido a la forma en que la vista de map almacena en caching sus annotations, NECESITA eliminar y volver a agregar la anotación si necesita realizar cambios en su apariencia. Un simple quitar y agregar es el path a seguir. No hay mecanismo de invalidation del caching, pero esto.

En realidad, no sé si esto funcionó para ti, pero así es como lo hice.

No necesitaba eliminar la anotación del map. Todo lo que necesito hacer es decirle al map que me dé la vista de anotación para una anotación de parámetro. El map devolverá la anotación correcta. A partir de ahí, tengo una propiedad para mi anotación personalizada para identificar si es un elemento activo, si es así, muestre la image del pin normal, de lo contrario muestre la image completa del pin.

 -(void)updateAnnotationImage:(CustomAnnotation *)paramAnnotation { MKAnnotationView *av = [geoMap viewForAnnotation:paramAnnotation]; if (paramAnnotation.active) { av.image = [UIImage imageNamed:@"PinNormal.png"]; } else { av.image = [UIImage imageNamed:@"PinFull.png"]; } } 

Poco tarde, pero espero que ayude a otros que se toparon con este problema.

También encontré útil esta respuesta: ¿ En qué caso se llamará mapView: viewForAnnotation:?

Cada vez que llame al método addAnnotation

 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id < MKAnnotation >)annotation gets called. 

Swift 2.1:

Tuve el mismo problema, encontré una solución rápida, activé esto cuando era necesario, también sería prudente enviarlo al hilo principal:

 var annotationsArray = mapView.annotations mapView.removeAnnotations(mapView.annotations) mapView.addAnnotations(arrayIncs) arrayIncs.removeAll()