2011-07-06 5 views
8

Aktualnie dodajem adnotacje do mojej mapy przez pętlę ... ale adnotacje pojawiają się tylko na mojej mapie w grupach. Poza tym, tylko na adnotacjach wyświetlanych jest tylko około 4 adnotacji, ale gdy przesuniemy mapę, pojawiają się nagle wszystkie adnotacje, które powinny tam być.MapView - pojawiają się adnotacje po jednym na raz

Jak mogę uzyskać wszystkie adnotacje, aby załadować w odpowiednim miejscu, po jednym na raz?

Z góry dziękuję!

Oto kod używam, aby dodać adnotacje:

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

Czy możesz dodać swój kod, aby dodać adnotacje? –

+0

Właśnie dodano. Dzięki! –

+0

Dzięki! Czy możesz również opublikować metodę viewForAnnotation:? –

Odpowiedz

1

Adam

To rozwiązanie jest nieco niechlujny jak musiałem munge się jedną z moich bieżących projektów do testowania, ale mam nadzieję, że to będzie pracować dla Ciebie.

Najpierw wyjaśnienie, ważne jest oddzielenie danych od prezentacji interfejsu użytkownika. [Dodatkowe komentarze do MKMapView] są po prostu aktualizacją danych do MKMapView i nie mają bezpośredniego wpływu na animację ani czas.

Delegat metoda MapView: didAddAnnotationViews: gdzie wszystkie niestandardowego zachowania prezentacji powinny zostać zdefiniowane. W Twoim opisie nie chcesz, aby pojawiały się wszystkie naraz, więc musisz sekwencjonować animacje, zamiast wykonywać je jednocześnie.

Jedną z metod jest dodanie wszystkich adnotacji naraz, a następnie dodanie ich wraz ze wzrostem opóźnień animacji, jednak nowe adnotacje dodane z dowolnego powodu ponownie rozpoczną animację od zera.

Poniższa metoda ustawia kolejkę animacji self.pendingViewsForAnimation (NSMutableArray) do przechowywania widoków adnotacji po ich dodaniu, a następnie sekwencyjnie łączy łańcuchy animacji.

Mam zastąpił animacji klatek z alfa skupić się na problemie animacji, aby oddzielić go od wydawania niektórych elementów nie występujących. Więcej o tym po kodzie ...

// 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]; 
} 

Jeśli chodzi o twój drugi numer, przedmioty nie zawsze pojawiają się, dopóki nie przeniesiesz mapy. Nie widzę żadnych oczywistych błędów w kodzie, ale oto kilka rzeczy chciałbym zrobić, aby wyizolować problem:

  1. tymczasowo usunąć swój MapView: didAddAnnotationViews :, MapView: annotationForView: i innych niestandardowych zachowań, aby zobaczyć jeśli domyślne zachowanie działa.
  2. Sprawdź, czy masz ważny adnotacji na addAnnotation. Zadzwonić i że współrzędne są widoczne (użyj [MapView visibleMapRect] MKMapRectContainsPoint() i MKMapPointForCoordinate()
  3. Jeśli nadal nie działa, spójrz na którym wywołujesz kod dodawania adnotacji z. Próbuję uniknąć wykonywania połączeń adnotacji podczas ruchu mapy za pomocą performSelector: withObject: afterDelay. Możesz poprzedzić to za pomocą [NSObject cancelPreviousPerformRequestsWithTarget: selector: object:], aby utworzyć niewielkie opóźnienie przed załadowaniem adnotacje na wypadek, gdyby mapa była przenoszona na duże odległości z wielokrotnymi przesunięciami.

Ostatni punkt, aby uzyskać efekt pin-drop, którego szukasz, prawdopodobnie chcesz przesunąć o stałą odległość od oryginalnego obiektu, zamiast polegać na adnotacjiVisibleRect. Twoja obecna implementacja spowoduje, że sworznie będą poruszać się z różnymi prędkościami w zależności od ich odległości od krawędzi. Przedmioty u góry będą powoli przesuwać się na miejsce, a przedmioty na dole będą latać szybko na swoim miejscu. Domyślna animacja Apple zawsze spada z tej samej wysokości. Przykład jest tutaj: How can I create a custom "pin-drop" animation using MKAnnotationView?

Mam nadzieję, że to pomaga.

Aktualizacja: Aby zademonstrować ten kod w akcji mam dołączony link do zmodyfikowanej wersji demo sejsmicznych Apple z następującymi zmianami:

  1. Zmieniono Earthquake.h/m, aby być MKAnnotation object
  2. Dodany SeismicMapViewController.h/m z powyższym kodem
  3. Aktualizacja RootViewController.h/m, aby otworzyć widok mapy jako modalnego stronie

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

+0

Wow! Dzięki, Barney. Dodałem twój kod ... bez błędów ... ale teraz nie ma żadnych adnotacji pojawiających się na mapie. Będę grał trochę z kodem, ale daj mi znać, jeśli to ma sens, dlaczego tak się stanie. –

+0

Zrobiłem kilka testów ... dowiedziałem się, że '- (void) processPendingViewsForAnimations' nie przechodzi przez' jeśli ([self.pendingViewsForAnimation count] == ​​0) return; ' –

+0

Adam, kod, który wysłałem pracował w Aplikacja testowałem, ale muszę ją przetworzyć na próbkę, aby upewnić się, że masz wszystko, czego potrzebujesz. Może być kilka dni, zanim będę mógł uzyskać powyższe informacje. Bądźcie czujni. (I upewnij się, że przydzieliłeś tablicę do swojego konstruktora (może to być initWithNibNamed lub initWithCoder lub ... inny, więc upewnij się, że jest wywoływany) –

0

Będziesz musiał wstrzymać aktualizacją po dodaniu każdej adnotacji i pozwolić na mapie, aby mieć czas, aby odświeżyć.

+0

Cześć Phil ... Jaki jest najlepszy sposób na zrobienie tego? Czy to jest zła praktyka? –