2012-05-27 23 views
13

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

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

Aquí es mi viewForAnnotation código:

- (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í es el código en la que agrego el pasador:

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 falta. viewForAnnotation obviamente está funcionando, ¡simplemente no se llama después del agregado inicial! ¡Si llamara a esta función, estoy 100% seguro de que funcionaría como lo hace el cambio de color si reinicio la aplicación!

EDITAR: Ah, y realmente no quiero empezar a eliminar anotaciones y volver a agregarlas. ¡Es lo que estoy haciendo a corto plazo de todos modos!

Respuesta

12

Debido a la forma en que la vista del mapa almacena en caché sus anotaciones, NECESITA eliminar y volver a agregar la anotación si necesita hacer cambios en su apariencia. Un simple eliminar & agregar es el camino a seguir. No hay mecanismo invalidante de caché, pero esto.

+0

Ah, gracias. Realmente no quería hacerlo de esa manera, pero logré retener la vista del texto destacado, ¡así que ahora no puedes decirlo de todos modos! Voy a marcar esto como la respuesta ya que no sabía que esta era la única manera. –

+0

No, no es la respuesta correcta, ver a continuación –

+0

Esto no funciona. – Aggressor

36

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

No es necesario que borre la anotación del mapa. Todo lo que necesito hacer es decirle al mapa que me dé la vista de anotación para una anotación de parámetro. El mapa 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í, mostrar la imagen de contacto normal, de lo contrario, mostrar la imagen de contacto completo.

-(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 encontraron con este problema.

+0

Esto es posible y esta es la forma correcta .. +1 para la respuesta. –

+0

Esto realmente debería ser la respuesta aceptada. ¡Gracias! – lostintranslation

0

Swift 2.1:

que tenían el mismo problema, y ​​halló una solución rápida, desencadenar esto cuando necesario, también enviarlo al hilo principal sería sabio:

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