MapView - аннотации появляются по одному - PullRequest
8 голосов
/ 06 июля 2011

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

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

Заранее спасибо!

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

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

Ответы [ 2 ]

1 голос
/ 13 июля 2011

Адам

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

Сначала объяснение, важно отделить данные от представления пользовательского интерфейса. [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. Если он все еще не работает, посмотрите, откуда вы вызываете код добавления аннотаций. Я стараюсь избегать вызовов аннотаций во время движения карты, используя executeSelector: withObject: afterDelay. Вы можете добавить к этому [NSObject cancelPreviousPerformRequestsWithTarget: selector: object:], чтобы создать небольшую задержку перед загрузкой аннотаций в случае, если карта перемещается на большое расстояние несколькими пальцами.

И еще одно замечание: для достижения необходимого эффекта закрепления булавки вы, вероятно, захотите сместить его на фиксированное расстояние от исходного объекта вместо зависимости от annotationVisibleRect. Ваша текущая реализация приведет к тому, что штифты будут двигаться с разными скоростями в зависимости от их расстояния от края. Элементы в верхней части будут медленно перемещаться на место, в то время как элементы в нижней части будут быстро летать на свои места. Анимация Apple по умолчанию всегда падает с одной высоты. Вот пример: Как я могу создать собственную анимацию с помощью MKAnnotationView?

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

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

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

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

0 голосов
/ 12 июля 2011

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

...