MapView - 使注释逐个出现

9
我目前正在通过循环向地图添加注释...但是这些注释只以组的方式出现在我的地图上。此外,在加载时,实际上只有大约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];
    }
}

你能发布一下添加注释的代码吗? - Nick B
谢谢!您能同时发布viewForAnnotation:方法吗? - Nick B
有什么建议吗,Nick?感谢你的帮助。 - Adam Storr
你是从哪个方法调用循环来填充你的注释的? - Chip Coons
它在一个名为loadmap的方法中运行,该方法在一个线程中运行:[NSThread detachNewThreadSelector: @selector(loadMap) toTarget:self withObject:nil];viewWillAppear内部。 - Adam Storr
显示剩余2条评论
2个回答

1

Adam,

这个解决方案有些混乱,因为我必须改动我的一个项目来测试,但希望这对你有所帮助。

首先,将数据与UI表示分离非常关键。[MKMapView addAnnotation(s)] 只是对 MKMapView 进行数据更新,不会直接影响动画或时间。

委托方法 mapView:didAddAnnotationViews: 是定义所有自定义表示行为的地方。根据您的描述,您不希望它们同时出现,因此需要按顺序执行动画而不是同时执行。

一种方法是立即添加所有注释,然后仅使用递增的动画延迟进行添加,但是无论出于何种原因添加新注释的时候都将从零开始进行动画。

以下方法设置了一个动画队列 self.pendingViewsForAnimation (NSMutableArray) 来保存添加的注释视图,并依次链接动画。

我用 alpha 替换了框架动画,以便将注意力集中在动画问题上,以使其与某些项目未显示的问题分开。更多内容请参见代码后面...

// 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:]来在加载注释之前创建一个轻微的延迟,以防地图被多次滑动移动了很长的距离。

最后一个要点是,为了实现您想要的针落效果,您可能希望从原始对象偏移固定距离,而不是依赖于annotationVisibleRect。您当前的实现将导致针根据其与边缘的距离移动速度不同。顶部的项目将缓慢移动到位,而底部的项目将快速飞入到位。苹果的默认动画总是从相同的高度下降。这里有一个例子:如何使用MKAnnotationView创建自定义“针落”动画?

希望这可以帮助您。

更新: 为了演示此代码的操作,我附上了一个修改过的Apple Seismic演示版本的链接,其中包括以下更改:

  1. 将Earthquake.h/m更改为MKAnnotation对象
  2. 添加了具有上述代码的SeismicMapViewController.h/m
  3. 更新了RootViewController.h/m以将地图视图作为模态页面打开

请参见:http://dl.dropbox.com/u/36171337/SeismicXMLWithMapDelay.zip


哇!谢谢Barney。我添加了你的代码...没有错误...但现在地图上没有任何注释出现。我会稍微调整一下代码,但如果你知道为什么会发生这种情况,请告诉我。 - Adam Storr
Adam,我发送的代码在我测试的应用程序中可以运行,但我需要将其拆分为示例以确保你拥有所需的所有内容。可能需要几天时间才能更新以上内容,请保持关注。(并确保你在构造函数中分配了数组(可以是initWithNibNamed或initWithCoder等其他方法,因此请确保它被调用)。) - Barney Mattox
谢谢巴尼...我期待着。 - Adam Storr
嗨,巴尼...有什么进展吗?感谢你的帮助。 - Adam Storr
巴尼,你发来的代码很好用...但是在我的应用程序中不起作用。我正在努力找出我的地图还有什么其他问题...我认为可能是因为多线程的原因... - Adam Storr
显示剩余3条评论

0

在添加每个注释后,您需要暂停更新并允许地图有时间刷新。


嗨Phil...最好的方法是什么?这是一个不好的做法吗? - Adam Storr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接