MapView - 一次出现一个注释

Ada*_*orr 8 iphone annotations android-mapview

我目前正通过循环向地图添加注释......但注释仅出现在我的地图上.此外,在加载时,地图上实际上只显示了大约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];
    }
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*tox 1

亚当,

这个解决方案有点混乱,因为我不得不修改我当前的项目之一来测试,但希望这对你有用。

首先解释一下,将数据与 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];
}
Run Code Online (Sandbox Code Playgroud)

关于您的第二个问题,在您移动地图之前,项目并不总是出现。我在您的代码中没有看到任何明显的错误,但我会采取以下一些措施来隔离问题:

  1. 暂时删除您的 mapView:didAddAnnotationViews:、mapView:annotationForView: 和任何其他自定义行为,以查看默认行为是否有效。
  2. 验证您在 addAnnotation: 调用中是否具有有效的注释,并且坐标是否可见(使用 [mapViewvisibleMapRect]、MKMapRectContainsPoint() 和 MKMapPointForCooperative()。
  3. 如果它仍然无法正常工作,请查看您从何处调用添加注释代码。我尝试使用 PerformSelector:withObject:afterDelay 来避免在地图移动期间进行注释调用。您可以在此之前使用 [NSObject cancelPreviousPerformRequestsWithTarget:selector:object:] 来在加载注释之前创建轻微的延迟,以防地图因多次滑动而移动很长的距离。

最后一点,为了实现您正在寻找的针落效果,您可能希望与原始对象偏移固定距离,而不是依赖annotationVisibleRect。您当前的实现将导致引脚以不同的速度移动,具体取决于它们距边缘的距离。顶部的物品将缓慢移动到位,而底部的物品将快速飞入到位。苹果的默认动画总是从相同的高度掉落。这里有一个例子:How can I create a custom "pin-drop"animation using MKAnnotationView?

希望这可以帮助。

更新: 为了演示此代码的实际效果,我附加了一个指向 Apple 地震演示的修改版本的链接,其中进行了以下更改:

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

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