2011-07-06 2 views
8

В настоящее время я добавляю аннотации к своей карте через цикл ... но аннотации появляются только на моей карте в группах. Кроме того, при загрузке на карте фактически отображаются только 4 аннотации ... но по мере того, как я немного перемещаю карту, все аннотации, которые должны быть там, внезапно появляются.MapView - появляются аннотации по одному

Как я могу получить все аннотации для загрузки в нужном месте по одному?

Заранее благодарен!

Вот код, я использую для добавления аннотаций:

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

Не могли бы вы разместить свой код, чтобы добавить аннотации? –

+0

Просто добавлено. Благодаря! –

+0

Спасибо! Не могли бы вы также опубликовать viewForAnnotation: метод? –

ответ

1

Адам,

Это решение немного грязный, как я должен был munge одну из моих текущих проектов, чтобы проверить, но, надеюсь, это будет работать для вас.

Во-первых, объяснение очень важно для разделения данных из представления пользовательского интерфейса. [MKMapView addAnnotation (s)] - это просто обновление данных для MKMapView и не оказывает прямого влияния на анимацию или время.

Метод делегата mapView: didAddAnnotationViews: здесь должно быть определено все поведение пользовательской презентации. В вашем описании вы не хотели, чтобы они появлялись сразу, поэтому вам нужно упорядочить анимацию, а не выполнять их одновременно.

Один из способов состоит в том, чтобы добавить все аннотации сразу, а затем просто добавить их с увеличением задержки анимации, однако новые аннотации, которые добавляются по какой-либо причине, снова начнут анимацию с нуля.

Метод ниже устанавливает очередь анимации self.pendingViewsForAnimation (NSMutableArray) для хранения представлений аннотаций по мере их добавления, а затем последовательно создает анимацию.

Я заменил анимацию кадра альфой, чтобы сосредоточиться на проблеме анимации, чтобы отделить ее от проблемы некоторых элементов, которые не появляются. Подробнее об этом после того, как код ...

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

Что касается вашего второго вопроса, элементы не всегда появляются, пока вы не переместите карту. Я не вижу каких-либо очевидных ошибок в коде, но здесь есть некоторые вещи, которые я бы сделать, чтобы изолировать проблему:

  1. Временно удалить ваш MAPview: didAddAnnotationViews :, MAPview: annotationForView: и любые другие пользовательские поведения, чтобы увидеть если поведение по умолчанию работает.
  2. Убедитесь, что у вас есть действующая аннотация на addAnnotation:. Вызов и координаты видны (используйте [MAPview visibleMapRect], MKMapRectContainsPoint(), и MKMapPointForCoordinate()
  3. Если он все еще не работает, посмотрите, где вы вызываете код добавления аннотаций. Я стараюсь избегать вызовов комментариев при движении карты с помощью функции performSelector: withObject: afterDelay. Вы можете предшествовать этому [NSObject cancelPreviousPerformRequestsWithTarget: selector: object:], чтобы создать небольшую задержку перед загрузкой аннотации в случае, если карта перемещается на большое расстояние с несколькими проходами.

Последнее, что необходимо для достижения эффекта штифта, вы, вероятно, хотите компенсировать фиксированное расстояние от исходного объекта, а не в зависимости от аннотацииVisibleRect. Ваша текущая реализация приведет к тому, что штыри движутся с разной скоростью в зависимости от их расстояния от края. Элементы в верхней части будут медленно перемещаться на место, в то время как предметы на дне будут быстро летать. Ядро Apple по умолчанию всегда падает с той же высоты. Пример: How can I create a custom "pin-drop" animation using MKAnnotationView?

Надеюсь, что это поможет.

Update: Чтобы продемонстрировать этот код в действии Я приложил ссылку на модифицированной версии сейсмической демо от Apple со следующими изменениями:

  1. Изменено Earthquake.h/м, чтобы быть MKAnnotation объект
  2. Добавлено SeismicMapViewController.h/м с кодом выше
  3. Изменен RootViewController.h/м, чтобы открыть вид карты как модальные страницы

См.: http://dl.dropbox.com/u/36171337/SeismicXMLWithMapDelay.zip

+0

Вау! Спасибо, Барни. Я добавил ваш код ... никаких ошибок ... но теперь на карте не появляются аннотации. Я немного поиграю с кодом, но дайте мне знать, если вам будет понятно, почему это произойдет. –

+0

Проделал некоторые тесты ... Я выяснил, что '- (void) processPendingViewsForAnimations' не делает его прошлым' if ([self.pendingViewsForAnimation count] == ​​0) return; ' –

+0

Adam, код, который я отправил, работал в приложение, которое я тестировал, но мне придется разбить его на образец, чтобы убедиться, что у вас есть все, что вам нужно. Может быть, пару дней, прежде чем я смогу получить вышеописанное. Будьте на связи. (И убедитесь, что вы выделили массив в своем конструкторе (может быть initWithNibNamed или initWithCoder или ... другим, поэтому убедитесь, что он вызван). –

0

Вам нужно будет приостановить обновление после добавления каждой аннотации и дайте карту, чтобы иметь время, чтобы обновить.

+0

Привет, Фил ... Каков наилучший способ сделать это? Это плохая практика? –

Смежные вопросы