2011-07-06 12 views
8

Actualmente estoy agregando anotaciones a mi mapa a través de un bucle ... pero las anotaciones solo aparecen en mi mapa en grupos. Además, con carga, solo se muestran unas 4 anotaciones en el mapa ... pero a medida que muevo el mapa un poco, aparecen todas las anotaciones que deberían estar ahí.Vista de mapa - Anotaciones aparecen una a la vez

¿Cómo puedo obtener todas las anotaciones para que se carguen en el lugar correcto, de a una por vez?

¡Gracias de antemano!

Aquí está el código que estoy usando para añadir anotaciones:

NSString *incident; 
      for (incident in weekFeed) { 
       NSString *finalCoordinates = [[NSString alloc] initWithFormat:@"%@", [incident valueForKey:@"coordinates"]]; 

       NSArray *coordinatesArray = [finalCoordinates componentsSeparatedByString:@","]; 

       latcoord = (@"%@", [coordinatesArray objectAtIndex:0]); 
       longcoord = (@"%@", [coordinatesArray objectAtIndex:1]); 

       // Final Logs 
       NSLog(@"Coordinates in NSString: [%@] - [%@]", latcoord, longcoord); 

       CLLocationCoordinate2D coord; 
       coord.latitude = [latcoord doubleValue]; 
       coord.longitude = [longcoord doubleValue]; 


       DisplayMap *ann = [[DisplayMap alloc] init]; 
       ann.title = [NSString stringWithFormat: @"%@", [incident valueForKey:@"incident_type"]]; 
       ann.subtitle = [NSString stringWithFormat: @"%@", [incident valueForKey:@"note"]]; 
       ann.coordinate = coord; 

       [mapView addAnnotation:ann]; 

       [ann release]; 
       } 


// Custom Map Markers 
-(MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation { 

    if ([annotation isKindOfClass:[MKUserLocation class]]) 
     return nil; //return nil to use default blue dot view 

    static NSString *AnnotationViewID = @"annotationViewID"; 
    MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID]; 

    if (annotationView == nil) { 
     annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease]; 
     } 

    annotationView.canShowCallout = YES; 

    if ([annotationView.annotation.title isEqualToString:@"one"]) { 
     UIImage *pinImage = [UIImage imageNamed:@"marker_1.png"]; 
     [annotationView setImage:pinImage]; 
     } 

    if ([annotationView.annotation.title isEqualToString:@"two"]) { 
     UIImage *pinImage = [UIImage imageNamed:@"marker_2.png"]; 
     [annotationView setImage:pinImage]; 
     } 

    annotationView.annotation = annotation; 
    return annotationView; 
    } 

- (void) mapView:(MKMapView *)mapV didAddAnnotationViews:(NSArray *)views { 
    CGRect visibleRect = [mapV annotationVisibleRect]; 
    for (MKAnnotationView *view in views) { 
     CGRect endFrame = view.frame; 

     CGRect startFrame = endFrame; startFrame.origin.y = visibleRect.origin.y - startFrame.size.height; 
     view.frame = startFrame; 

     [UIView beginAnimations:@"drop" context:NULL]; 
     [UIView setAnimationDuration:0.4]; 

     view.frame = endFrame; 

     [UIView commitAnimations]; 
    } 
} 
+0

¿Podría publicar su código para agregar anotaciones? –

+0

Acaba de agregarse. ¡Gracias! –

+0

¡Gracias! ¿Podría publicar el método viewForAnnotation también? –

Respuesta

1

Adam,

Esta solución es un poco complicado ya que tuve que munge uno de mis proyectos actuales para poner a prueba, pero espero que esto funcione para usted.

Primero una explicación, es fundamental separar los datos de la presentación de la interfaz de usuario. Las [MKMapView addAnnotation (s)] son ​​solo una actualización de datos para MKMapView y no tienen un impacto directo en la animación o el tiempo.

El método delegado mapView: didAddAnnotationViews: es donde se debe definir todo el comportamiento de presentación personalizado. En su descripción, no quería que aparecieran todos a la vez, por lo que debe secuenciar sus animaciones en lugar de realizarlas simultáneamente.

Un método consiste en agregar todas las anotaciones a la vez y luego agregarlas con el aumento de las demoras de la animación; sin embargo, las nuevas anotaciones que se agreguen por cualquier razón comenzarán nuevamente sus animaciones en cero.

El siguiente método configura una cola de animación self.pendingViewsForAnimation (NSMutableArray) para mantener las vistas de anotación a medida que se agregan y luego encadena la animación secuencialmente.

He reemplazado la animación de marco con alfa para enfocarme en el problema de animación para separarlo de la aparición de algunos elementos. Más sobre esto después de que el código ...

// Interface 
// ... 

// Add property or iVar for pendingViewsForAnimation; you must init/dealloc the array 
@property (retain) NSMutableArray* pendingViewsForAnimation; 

// Implementation 
// ... 
- (void)processPendingViewsForAnimation 
{ 
    static BOOL runningAnimations = NO; 
    // Nothing to animate, exit 
    if ([self.pendingViewsForAnimation count]==0) return; 
    // Already animating, exit 
    if (runningAnimations) 
     return; 

    // We're animating 
    runningAnimations = YES; 

    MKAnnotationView* view = [self.pendingViewsForAnimation lastObject]; 

    [UIView animateWithDuration:0.4 animations:^(void) { 
     view.alpha = 1; 
     NSLog(@"Show Annotation[%d] %@",[self.pendingViewsForAnimation count],view); 
    } completion:^(BOOL finished) { 
     [self.pendingViewsForAnimation removeObject:view]; 
     runningAnimations = NO; 
     [self processPendingViewsForAnimation]; 
    }]; 

} 

// This just demonstrates the animation logic, I've removed the "frame" animation for now 
// to focus our attention on just the animation.  
- (void) mapView:(MKMapView *)mapV didAddAnnotationViews:(NSArray *)views { 
    for (MKAnnotationView *view in views) { 
     view.alpha = 0; 

     [self.pendingViewsForAnimation addObject:view]; 
    } 
    [self processPendingViewsForAnimation]; 
} 

En cuanto a su segunda cuestión, los artículos no siempre están apareciendo hasta que mueva el mapa. No veo los errores obvios en su código, pero aquí hay algunas cosas que haría para aislar el problema:

  1. eliminar temporalmente su MAPview: didAddAnnotationViews :, MAPview: annotationForView: y cualesquiera otros comportamientos personalizados a ver si el comportamiento predeterminado funciona
  2. Compruebe que tiene una anotación válida en el addAnnotation:. Llamar y que las coordenadas son visibles (utiliza [MAPview visibleMapRect], MKMapRectContainsPoint(), y MKMapPointForCoordinate()
  3. Si aún no funciona, ver dónde está llamando al código de agregar anotaciones. Trato de evitar realizar llamadas de anotación durante el movimiento del mapa utilizando performSelector: withObject: afterDelay. Puede preceder esto con un [NSObject cancelPreviousPerformRequestsWithTarget: selector: object:] para crear un ligero retraso antes de la carga anotaciones en caso de que el mapa se mueva una larga distancia con múltiples golpes.

Un último punto, para lograr el efecto de pin-drop que está buscando, es probable que desee compensar una distancia fija del objeto original en lugar de depender de la anotación VisibleRect. Su implementación actual dará como resultado pines que se mueven a diferentes velocidades dependiendo de su distancia desde el borde. Los elementos en la parte superior se moverán lentamente en su lugar mientras que los elementos en la parte inferior volarán rápidamente en su lugar. La animación predeterminada de Apple siempre cae desde la misma altura. Un ejemplo está aquí: How can I create a custom "pin-drop" animation using MKAnnotationView?

Espero que esto ayude.

Actualización: Para demostrar este código en acción He adjuntado un enlace a una versión modificada de la versión parcial de programa sísmico de Apple con los siguientes cambios:

  1. cambiado Earthquake.h/m para ser un MKAnnotation objetar
  2. Agregado SeismicMapViewController.h/m con el código de
  3. Actualizado RootViewController.h/m para abrir la vista de mapa como una página modal

Ver: http://dl.dropbox.com/u/36171337/SeismicXMLWithMapDelay.zip

+0

¡Guau! Gracias, Barney. Agregué tu código ... no hay errores ... pero ahora no aparecen anotaciones en el mapa. Voy a jugar un poco con el código, pero avíseme si tiene sentido por qué sucedería eso. –

+0

Hice algunas pruebas ... Descubrí que '- (void) processPendingViewsForAnimations' no pasa de' if ([self.pendingViewsForAnimation count] == ​​0) return; ' –

+0

Adam, el código que envié trabajó en el aplicación que estaba probando, pero tendré que dividirla en una muestra para asegurarme de que tenga todo lo que necesita. Puede ser un par de días antes de que pueda actualizar lo anterior. Manténganse al tanto. (Y asegúrate de asignar la matriz en tu constructor (podría ser initWithNibNamed o initWithCoder o ... otro, así que asegúrate de que se llame). –

0

Usted tendrá que hacer una pausa en la actualización después de agregar cada anotación y permitir que el mapa tenga tiempo para refrescarse.

+0

Hola Phil ... ¿Cuál es la mejor manera de hacerlo? ¿Es esto una mala práctica? –

Cuestiones relacionadas