2011-12-19 17 views
12

Tengo un mapa y un conjunto de anotaciones, cada una con una propiedad "principal". Actualmente, cuando agrego anotaciones, implemento el método didAddAnnotationViews para animar esas anotaciones, por lo que parecen provenir de las coordenadas de sus padres. ¿Hay alguna manera de hacerlo durante la eliminación de anotaciones? Cuando elimino una anotación del mapa, quiero que se anime en su coordenada principal, y hasta donde yo sé, no existe un equivalente para didAddAnnotationViews para cuando se elimina una anotación.Animate eliminación de anotaciones

Respuesta

15

Animate la anotación antes de la quita del mapa y la elimina después de completar la animación. El código puede ser:

- (void) removeMyAnnotation:(MyAnnotation*)annotation{ 
    [UIView animateWithDuration:1.0f 
        animations:^(void){ 
         annotation.coordinate = annotation.parentAnnotation.coordinate; 
        } 
        completion:^(BOOL finished)completion{ 
         [mapView removeAnnotation:annotation]; 
        } 
} 
+0

Gracias - otra cosa, hay una manera de de acceder al MKAnnotationView correspondiente de la anotación para poder moverlo de esa forma? Debido a que mi clase de anotación calcula su coordenada de forma dinámica, no se puede configurar (a menos que agregue una carga de funcionalidad para establecer coordenadas personalizadas, que prefiero evitar). – benwad

+2

@benwad, puede obtenerlo utilizando el método viewForAnnotation en MKMapView, aunque no se garantiza que siempre devuelva la vista real (puede devolver nil si la anotación no está visible, por ejemplo) – Vladimir

+0

¿Qué es parentAnnotation? – malhal

5

Usted debe NO llamada diferir de removeAnnotation al igual que en la respuesta de Vladimir @ porque el estado de MKMapView podría ser cambiado durante la animación.

En el momento en el removeAnnotation se llama desde el bloque de terminación de animación, otras anotaciones se podrían añadir/retira de la MapView - por lo que, en algunos casos se puede llegar a la eliminación conjunto equivocado de anotaciones.

me escribió esta categoría para MKMapView puede utilizar para la eliminación de anotación animado en forma segura:

@interface MKMapView (RemoveAnnotationWithAnimation) 

- (void)removeAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated; 
- (void)removeAnnotations:(NSArray *)annotations animated:(BOOL)animated; 

@end 

y el archivo .m:

@implementation MKMapView (RemoveAnnotationWithAnimation) 

- (void)removeAnnotation:(id <MKAnnotation>)annotation animated:(BOOL)animated 
{ 
    [self removeAnnotations:@[annotation] animated:animated]; 
} 

- (void)removeAnnotations:(NSArray *)annotations animated:(BOOL)animated 
{ 
    if (animated) { 
     NSSet * visibleAnnotations = [self annotationsInMapRect:self.visibleMapRect]; 
     NSMutableArray * annotationsToRemoveWithAnimation = [NSMutableArray array]; 
     for (id<MKAnnotation> annotation in annotations) { 
      if ([visibleAnnotations containsObject:annotation]) { 
       [annotationsToRemoveWithAnimation addObject:annotation]; 
      } 
     } 
     NSMutableArray * snapshotViews = [NSMutableArray array]; 
     for (id<MKAnnotation> annotation in annotationsToRemoveWithAnimation) { 
      UIView * annotationView = [self viewForAnnotation:annotation]; 
      if (annotationView) { 
       UIView * snapshotView = [annotationView snapshotViewAfterScreenUpdates:NO]; 
       snapshotView.frame = annotationView.frame; 
       [snapshotViews addObject:snapshotView]; 
       [[annotationView superview] insertSubview:snapshotView aboveSubview:annotationView]; 
      } 
     } 
     [UIView animateWithDuration:0.5 
         animations:^{ 
          for (UIView * snapshotView in snapshotViews) { 
           // Change the way views are animated if you want 
           CGRect frame = snapshotView.frame; 
           frame.origin.y = -frame.size.height; 
           snapshotView.frame = frame; 
          } 
         } 
         completion:^(BOOL finished) { 
          for (UIView * snapshotView in snapshotViews) { 
           [snapshotView removeFromSuperview]; 
          } 
         }]; 
    } 
    [self removeAnnotations:annotations]; 
} 

@end 
+0

Implementé esta solución para borrar mis anotaciones. Esto no funciona cuando se panoramiza el mapa mientras las vistas de las instantáneas se están desvaneciendo, ya que permanecerán en blanco mientras se mueve el mapa. Se ve bastante extraño. – duncanc4

+0

Después de leer su comentario y pensar en la solución de @Vladimir, no veo cómo agregar o eliminar anotaciones diferentes durante la animación afecta la capacidad de eliminar la anotación específica cuando se ejecuta el bloque de finalización. El bloque captura el puntero, por lo que tiene la anotación exacta para eliminar. El único problema que pude ver es si algún otro código eliminó la anotación exacta que estaba animando. No estoy seguro de lo que 'MKMapView' hace si no tiene la anotación que está tratando de eliminar. – duncanc4

+0

@ duncanc4 El problema es que MKMapView reutiliza instancias de vista de anotación, como hace UITableView con sus celdas. Por lo tanto, si almacena un puntero a una anotación que se está eliminando y desplaza el mapa a otro grupo de anotaciones, puede terminar eliminando la anotación incorrecta cuando se ejecuta el bloque. – NAlexN