2011-12-19 16 views
12

Ho una mappa e un set di annotazioni, ognuna con una proprietà 'genitore'. Attualmente quando aggiungo annotazioni implemento il metodo didAddAnnotationViews per animare quelle annotazioni in modo che sembrino provenire dalle coordinate dei loro genitori. C'è un modo per farlo durante la rimozione delle annotazioni? Quando rimuovo un'annotazione dalla mappa, voglio che si animi nella sua coordinata principale e, per quanto ne so, non esiste un equivalente per didAddAnnotationViews per quando un'annotazione viene rimossa.Animare la rimozione di annotazioni

risposta

15

annotazione animata prima dello lo rimuovi dalla mappa ed esegui la rimozione al termine dell'animazione. Il codice può apparire come:

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

Grazie - un'altra cosa, c'è un modo di accedere al corrispondente MKAnnotationView dell'annotazione in modo da poterlo spostare in quel modo? Perché la mia classe di annotazione calcola le sue coordinate dinamicamente in modo che non possa essere impostata (a meno che non aggiungo un carico di funzionalità per l'impostazione di coordinate personalizzate, che preferirei evitare). – benwad

+2

@benwad, è possibile ottenerlo utilizzando il metodo viewForAnnotation in MKMapView, sebbene non sia garantito restituire sempre la vista effettiva (può restituire nil se l'annotazione non è visibile per esempio) – Vladimir

+0

Che cos'è parentAnnotation? – malhal

5

Si dovrebbe NON rinviare chiamata del removeAnnotation come in @ risposta di Vladimir a causa dello stato di MKMapView potrebbe essere modificato durante l'animazione.

Con il tempo il removeAnnotation viene chiamato dal blocco completamento di animazione, si potrebbe aggiungere un altro annotazioni/rimossi dalla MapView - così, in alcuni casi, si può finire per la rimozione di gruppo errato di annotazioni.

Ho scritto questa categoria per MKMapView è possibile utilizzare per la rimozione delle annotazioni animato in modo sicuro:

@interface MKMapView (RemoveAnnotationWithAnimation) 

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

@end 

e il file .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

Ho implementato questa soluzione per svanire le mie annotazioni. Questo non funziona quando si esegue il panning della mappa mentre le viste dell'istantanea stanno svanendo, mentre rimarranno in ordine mentre la mappa si sposta. Sembra piuttosto strano – duncanc4

+0

Dopo aver letto il tuo commento e pensato alla soluzione di @ Vladimir, non vedo come aggiungere o rimuovere annotazioni diverse durante gli effetti di animazione la possibilità di rimuovere l'annotazione specifica quando viene eseguito il blocco di completamento. Il blocco acquisisce il puntatore, quindi ha l'annotazione esatta da rimuovere. L'unico problema che ho potuto vedere è se qualche altro codice ha rimosso l'annotazione esatta che stava animando. Non sono sicuro di cosa 'MKMapView' fa se non ha l'annotazione che stai cercando di rimuovere. – duncanc4

+0

@ duncanc4 Il problema è che MKMapView riutilizza le istanze di visualizzazione annotazioni, come fa UITableView con le sue celle. Pertanto, se si memorizza un puntatore a un'annotazione che viene rimossa e si scorre la mappa in un altro gruppo di annotazioni, si può finire per rimuovere un'annotazione errata quando il blocco viene eseguito. – NAlexN

Problemi correlati