MapView - 一次显示一个注释 [英] MapView - Have Annotations Appear One at a Time

查看:27
本文介绍了MapView - 一次显示一个注释的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在通过循环向我的地图添加注释...但注释仅成组出现在我的地图上.此外,在加载时,地图上实际上只显示了大约 4 个注释……但是当我稍微移动地图时,所有应该在那里的注释突然出现.

I'm currently adding annotations to my map through a loop... but the annotations are only appearing on my map in groups. Also, on load, only about 4 annotations are actually displayed on the map... but as I move the map a little, all of the annotations that should be there, suddenly appear.

如何将所有注释加载到正确的位置,一次加载一个?

How can I get all of the annotations to load in the right place, one at a time?

提前致谢!

这是我用来添加注释的代码:

Here is the code I'm using to add annotations:

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

推荐答案

Adam,

这个解决方案有点混乱,因为我不得不对我当前的一个项目进行测试,但希望这对你有用.

This solution is a bit messy as I had to munge up one of my current projects to test, but hopefully this will work for you.

首先解释一下,将数据与 UI 呈现分开至关重要.[MKMapView addAnnotation(s)] 只是对 MKMapView 的数据更新,对动画或计时没有直接影响.

First an explanation, it's critical to separate data from UI presentation. The [MKMapView addAnnotation(s)] are just a data update to MKMapView and have no direct impact on animation or timing.

委托方法 mapView:didAddAnnotationViews: 是应该定义所有自定义呈现行为的地方.在您的描述中,您不希望这些动画同时出现,因此您需要对动画进行排序,而不是同时执行它们.

The delegate method mapView:didAddAnnotationViews: is where all of the custom presentation behavior should be defined. In your description you didn't want these to appear all at once, so you need to sequence your animations instead of performing them simultaneously.

一种方法是一次性添加所有注释,然后在增加动画延迟的情况下添加它们,但是无论出于何种原因添加的新注释都将再次从零开始动画.

One method is to add all of the annotations at once and then just add them with increasing animation delays, however new annotations that get added for whatever reason will begin their animations at zero again.

下面的方法设置一个动画队列 self.pendingViewsForAnimation (NSMutableArray) 来保存添加的注释视图,然后按顺序链接动画.

The method below sets up an animation queue self.pendingViewsForAnimation (NSMutableArray) to hold annotation views as they are added and then chains the animation sequentially.

我已将帧动画替换为 alpha 以专注于动画问题,将其与某些项目未出现的问题分开.在代码之后更多关于这个...

I've replaced the frame animation with alpha to focus on the animation problem to separate it from the issue of some items not appearing. More on this after the code...

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

关于您的第二个问题,在您移动地图之前,项目并不总是出现.我在你的代码中没有看到任何明显的错误,但我会做一些事情来隔离问题:

Regarding your second issue, items are not always appearing until you move the map. I don't see any obvious errors in your code, but here are some things I would do to isolate the problem:

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

最后一点,要实现您正在寻找的针落效果,您可能希望与原始对象偏移固定距离,而不是依赖于 annotationVisibleRect.您当前的实现将导致引脚以不同的速度移动,具体取决于它们与边缘的距离.顶部的物品会慢慢移动到位,而底部的物品会快速飞到位.Apple 的默认动画总是从同一高度下降.一个例子在这里:我如何创建一个自定义针落"使用 MKAnnotationView 制作动画?

One last point, to achieve the pin-drop effect you're looking for, you probably want to offset by a fixed distance from the original object instead of depending on annotationVisibleRect. Your current implementation will result in pins moving at different speeds depending on their distance from the edge. Items at the top will slowly move into place while items at the bottom will fly rapidly into place. Apple's default animation always drops from the same height. An example is here: How can I create a custom "pin-drop" animation using MKAnnotationView?

希望这会有所帮助.

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

Update: To demonstrate this code in action I've attached a link to a modified version of Apple's Seismic demo with the following changes:

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

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

这篇关于MapView - 一次显示一个注释的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆