MapView类 - 有注解上一次只能显示一 [英] MapView - Have Annotations Appear One at a Time

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

问题描述

我目前通过循环添加注解我的地图...但注释只能出现在我的组图谱。此外,在负荷,只有约4注释实际显示在地图上......但我移动地图一点,所有的注释应该是存在的,突然出现。

我怎样才能得到所有的注解在正确的地方加载,一次一个?

在此先感谢!

下面是code我使用添加注释:

 的NSString *事件;
            对于(事件weekFeed){
                * NSString的finalCoordinates = [[NSString的页头] initWithFormat:@%@,[事件valueForKey:@坐标]];                的NSArray * coordinatesArray = [finalCoordinates componentsSeparatedByString:@,];                latcoord =(@%@,[coordinatesArray objectAtIndex:0]);
                longcoord =(@%@,[coordinatesArray objectAtIndex:1]);                //最后的日志
                的NSLog(@坐标中的NSString:[%@] - [%@],latcoord,longcoord);                CLLocationCoordinate2D坐标;
                coord.latitude = [latcoord的doubleValue];
                coord.longitude = [longcoord的doubleValue];
                DisplayMap *安= [[DisplayMap的alloc]初始化];
                ann.title = [的NSString stringWithFormat:@%@,[事件valueForKey:@incident_type]];
                ann.subtitle = [的NSString stringWithFormat:@%@,[事件valueForKey:@注意]];
                ann.coordinate =坐标;                [图形页面addAnnotation:安];                [安发布]
                }
//自定义地图标记
- (MKAnnotationView *)的MapView:(*的MKMapView)的地图viewForAnnotation:(ID< MKAnnotation>){注解    如果([注解isKindOfClass:[MKUserLocation类])
        回零; //返回零使用默认的蓝点看法    静态的NSString * AnnotationViewID = @annotationViewID
    MKAnnotationView * annotationView =(MKAnnotationView *)[图形页面dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];    如果(annotationView ==无){
        annotationView = [[[MKAnnotationView页头] initWithAnnotation:注释reuseIdentifier:AnnotationViewID]自动释放];
        }    annotationView.canShowCallout = YES;    如果([annotationView.annotation.title isEqualToString:@一]){
        *的UIImage = pinImage [UIImage的imageNamed:@marker_1.png];
        [annotationView setImage:pinImage];
        }    如果([annotationView.annotation.title isEqualToString:@二]){
        *的UIImage = pinImage [UIImage的imageNamed:@marker_2.png];
        [annotationView setImage:pinImage];
        }    annotationView.annotation =注释;
    返回annotationView;
    } - (无效)MapView类:(*的MKMapView)mapV didAddAnnotationViews:(NSArray的*)的意见{
    的CGRect的visibleRect = [mapV annotationVisibleRect]
    对于(MKAnnotationView *在视图中查看){
        的CGRect endFrame = view.frame;        的CGRect startFrame将= endFrame; startFrame.origin.y = visibleRect.origin.y - startFrame.size.height;
        view.frame = startFrame将;        [UIView的beginAnimations:@降方面:NULL];
        [UIView的setAnimationDuration:0.4];        view.frame = endFrame;        [UIView的commitAnimations];
    }
}


解决方案

亚当,

这解决方案是一个有点乱,因为我不得不munge了我目前的项目进行测试的一种,但希望这会为你工作。

首先说明,这是从UI presentation单独的​​数据是至关重要的。在[的MKMapView addAnnotation(S)只是一个数据更新的MKMapView和对动画或时间没有直接的影响。

委托方法的MapView:didAddAnnotationViews:是所有的定制presentation行为加以界定。在你的描述你不想这些出现一次全部,所以你需要你的序列,而不是动画,同时执行它们。

一种方法是添加的所有注释一次,然后只需添加它们随着动画的延迟,即得到补充出于什么原因将再次零开始他们的动画然而新的注解。

下面的方法设置了一个动画队列self.pendingViewsForAnimation(NSMutableArray的)持有的注解视图,因为它们添加动画,然后按顺序链。

我已经取代了帧动画与Alpha专注于动画的问题它的一些项目没有出现问题分开。更多关于此之后,code ...

  //接口
// ...//添加属性或伊娃的pendingViewsForAnimation;必须初始化/的dealloc数组
@property(保留)的NSMutableArray * pendingViewsForAnimation;//实施
// ...
- (无效)processPendingViewsForAnimation
{
    静态BOOL runningAnimations = NO;
    //没有动画,退出
    如果([self.pendingViewsForAnimation计数] == 0)回报;
    //已经动画,退出
    如果(runningAnimations)
        返回;    //我们动画
    runningAnimations = YES;    MKAnnotationView *视图= [self.pendingViewsForAnimation lastObject]    [UIView的animateWithDuration:0.4动画:^(无效){
        view.alpha = 1;
        的NSLog(@显示注释内容[%d]%@,[self.pendingViewsForAnimation数],查看);
    }完成:^(BOOL完){
        [self.pendingViewsForAnimation的removeObject:视图]
        runningAnimations = NO;
        [个体经营processPendingViewsForAnimation]
    }];}//这只是演示动画的逻辑,我已经删除了帧动画现在
//把我们的注意力只在动画。
- (无效)MapView类:(*的MKMapView)mapV didAddAnnotationViews:(NSArray的*)的意见{
    对于(MKAnnotationView *在视图中查看){
        view.alpha = 0;        [self.pendingViewsForAnimation ADDOBJECT:视图]
    }
    [个体经营processPendingViewsForAnimation]
}

关于你的第二个问题,项目并不总是出现,直到您移动地图。我没有看到你的code任何明显的错误,但这里有一些事情我会做隔离问题:


  1. 暂时删除您的图形页面:didAddAnnotationViews :,图形页面:annotationForView:和任何其他自定义行为,看是否默认行为适用

  2. 确认您拥有在addAnnotation有效译注:打电话的坐标是可见的(使用[图形页面visibleMa preCT] MKMa prectContainsPoint()和MKMapPointForCoordinate()

  3. 如果它仍然不能正常工作,看你在哪里调用从添加注释code。我尝试使用performSelector来避免运动地图制作过程中的注释呼叫:withObject:afterDelay。您可以precede这与[NSObject的取消previousPerformRequestsWithTarget:选择:对象:]创建之前加载注释稍有延迟的情况下,地图上被移动多挥笔长途

最后一点,要实现你要找的引脚放置效果,你可能想通过从原始对象而不是依赖于annotationVisibleRect一个固定的距离,以抵消。当前的实施将导致销在根据来自边缘的距离不同的速度移动。在顶部的项目会慢慢地移动到位,而在底部的项目将迅速飞入到位。苹果的默认的动画总是从相同的高度下降。一个例子是在这里:<一href=\"http://stackoverflow.com/questions/1857160/how-can-i-create-a-custom-pin-drop-animation-using-mkannotationview\">How我可以创建自定义的&QUOT;销降&QUOT;使用MKAnnotationView动画?

希望这有助于。

更新:
为了证明这个行动code,我附上以下更改链接到苹果的地震演示的修改版本:


  1. 改变Earthquake.h /平方米是一个MKAnnotation对象

  2. 新增SeismicMapViewController.h /平方米以上code

  3. 更新RootViewController.h / M打开地图视图为模式页

请参阅: http://dl.dropbox.com/u/36171337/SeismicXMLWithMapDelay。拉链

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?

Thanks in advance!

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.

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.

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.

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.

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. Temporarily remove your mapView:didAddAnnotationViews:, mapView:annotationForView: and any other custom behaviors to see if default behavior works.
  2. Verify that you have a valid Annotation at the addAnnotation: call and that the coordinates are visible (use [mapView visibleMapRect], MKMapRectContainsPoint(), and MKMapPointForCoordinate().
  3. If it is still not functioning, look at where you are calling the add annotations code from. I try to avoid making annotation calls during map movement by using performSelector:withObject:afterDelay. You can precede this with an [NSObject cancelPreviousPerformRequestsWithTarget:selector:object:] to create a slight delay prior to loading annotations in case the map is being moved a long distance with multiple swipes.

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?

Hope this helps.

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. Changed Earthquake.h/m to be an MKAnnotation object
  2. Added SeismicMapViewController.h/m with above code
  3. Updated RootViewController.h/m to open the map view as a modal page

See: http://dl.dropbox.com/u/36171337/SeismicXMLWithMapDelay.zip

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

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