如何在不触及引脚的情况下触发MKAnnotationView的标注视图?

时间:2009-06-11 01:30:11

标签: iphone

我正在使用通常的彩色针作为位置点MKMapView。我希望能够在不触及销钉的情况下显示标注。

我该怎么做?在注释视图上调用setSelected:YES没有做任何事情。我正在考虑模拟针上的触摸,但我不知道该怎么做。

13 个答案:

答案 0 :(得分:62)

但有一个方法可以让benvolioT的解决方案起作用,即代码

for (id<MKAnnotation> currentAnnotation in mapView.annotations) {       
    if ([currentAnnotation isEqual:annotationToSelect]) {
        [mapView selectAnnotation:currentAnnotation animated:FALSE];
    }
}
应该从- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView调用

,而不是其他地方。

第一次加载地图时,调用viewWillAppear viewDidAppear UIViewController- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView等各种方法的顺序不同位置以及随后的地图以相同的位置显示。这有点棘手。

答案 1 :(得分:34)

好的,这是解决这个问题的方法。

要使用MKMapView的{​​{1}}方法显示标注。

答案 2 :(得分:32)

假设您想要选择最后一个注释视图,您可以将代码放在下面:

[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];

在下面的代表中:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
    //Here
    [mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
}

答案 3 :(得分:21)

好的,要成功添加Callout,您需要使用委托的didAddAnnotationViews添加所有注释视图后调用selectAnnotation:animated:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views{
    for (id<MKAnnotation> currentAnnotation in mapView.annotations) {       
        if ([currentAnnotation isEqual: annotationToSelect]) {
            [mapView selectAnnotation:currentAnnotation animated:YES];
        }
    }
}

答案 4 :(得分:12)

在尝试了这个帖子的各种答案之后,我终于想出了这个。它非常可靠,我还没有看到它失败:

- (void)mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views;
{
    for(id<MKAnnotation> currentAnnotation in aMapView.annotations) 
    {       
        if([currentAnnotation isEqual:annotationToSelect]) 
        {
            NSLog(@"Yay!");
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_current_queue(), ^
            {
                [aMapView selectAnnotation:currentAnnotation animated:YES];
            });
        }
    }
}

该块用于稍微延迟,因为没有它,标注可能无法正确显示。

答案 5 :(得分:9)

这对我不起作用。我怀疑MapKit API中存在一个错误。

有关此人无效的其他人的详细信息,请参阅此链接: http://www.iphonedevsdk.com/forum/iphone-sdk-development/19740-trigger-mkannotationview-callout-bubble.html#post110447

- 编辑 -

好的,在搞了一段时间之后,这就是我能够做的工作:

for (id<MKAnnotation> currentAnnotation in mapView.annotations) {       
    if ([currentAnnotation isEqual:annotationToSelect]) {
        [mapView selectAnnotation:currentAnnotation animated:FALSE];
    }
}

注意,这需要为实现MKAnnotation协议的类实现- (BOOL)isEqual:(id)anObject

答案 6 :(得分:6)

如果你只想打开你添加的最后一个注释的标注,试试这个,对我有用。

[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];

答案 7 :(得分:5)

我仔细阅读了API,最后我发现了问题:


如果指定的注释不在屏幕上,因此没有关联的注释视图,则此方法无效。

因此您可以等待一段时间(例如,3秒),然后执行此操作。然后就行了。

答案 8 :(得分:5)

selectAnnotation调用- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView的问题在于,顾名思义,此事件仅在MapView最初加载时触发,因此如果最初加载,则无法触发注释的标注在MapView完成加载后添加它。

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views调用它的问题是,当调用selectAnnotation时,您的注释可能不在屏幕上,这会导致它无效。即使您在添加注释之前将MapView的区域居中到注释的坐标,设置MapView区域所需的轻微延迟也足以在注释在屏幕上可见之前调用selectAnnotation,尤其是在您设置动画时setRegion

有些人在延迟之后致电selectAnnotation解决了这个问题:

-(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
    [self performSelector:@selector(selectLastAnnotation)
        withObject:nil afterDelay:1];
}

-(void)selectLastAnnotation {
    [myMapView selectAnnotation:
        [[myMapView annotations] lastObject] animated:YES];
}

但即便如此,您可能会得到奇怪的结果,因为注释可能需要一秒多的时间才能显示在屏幕上,具体取决于各种因素,例如您之前的MapView区域与新区域之间的距离或您的Internet连接速度。< / p>

我决定从- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated拨打电话,因为它确保注释实际在屏幕上(假设您将MapView的区域设置为注释的坐标),因为此事件在之后触发 > setRegion(及其动画)已完成。但是,只要MapView的区域发生变化,就会触发regionDidChangeAnimated,包括当用户只是在地图周围移动时,您必须确保有条件正确识别何时是触发注释标注的正确时间。

我是这样做的:

MKPointAnnotation *myAnnotationWithCallout;

- (void)someMethod {
    MKPointAnnotation *myAnnotation = [[MKPointAnnotation alloc] init];
    [myAnnotation setCoordinate: someCoordinate];
    [myAnnotation setTitle: someTitle];

    MKCoordinateRegion someRegion =
       MKCoordinateRegionMakeWithDistance (someCoordinate, zoomLevel, zoomLevel);

    myAnnotationWithCallout = myAnnotation;
    [myMapView setRegion: someRegion animated: YES];
    [myMapView addAnnotation: myAnnotation];
}

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    if (myAnnotationWithCallout)
    {
        [mapView selectAnnotation: myAnnotationWithCallout animated:YES];
        myAnnotationWithCallout = nil;
    }
}

这样,您的注释会在selectAnnotation被调用时保证在屏幕上显示,if (myAnnotationWithCallout)部分确保除- (void)someMethod中的区域设置之外的区域设置不会触发标注。

答案 9 :(得分:3)

由于像benvolioT所示的代码,我怀疑存在于系统中,当我使用selectAnnotation:animation:方法时,它没有显示callOut,我猜测原因是因为它已经被选中了它避免要求MapView使用注释标题和副标题在地图上重绘callOut。

因此,解决方案只是首先取消选择它并重新选择它。

首先,我需要在Apple的touchMoved方法中执行此操作(即如何拖动AnnotationView)以隐藏callOut。 (仅仅使用annotation.canShowAnnotation = NO单独不起作用,因为我怀疑它需要重绘.deselectAnnotaiton会导致必要的操作。另外,单独取消选择没有做到这一点,callOut只消失了一次并立即重新绘制。是暗示它被自动重新选择了。

annotationView.canShowAnnotation = NO;
[mapView deselectAnnotation:annotation animated:YES];

然后,只需在touchEnded方法中使用下面的代码就不会带回callOut(此时系统已自动选择了注释,并且可能重新调用callOut的重新绘制):

annotationView.canShowAnnotation = YES;
[mapView selectAnnotation:annotation animated:YES];

解决方案是:

annotationView.canShowAnnotation = YES;
[mapView deselectAnnotation:annotation animated:YES];
[mapView selectAnnotation:annotation animated:YES];

这只是买回了callOut,可能是它重新启动了mapView重绘callOut的过程。

严格来说,我应该检测注释是否是当前注释(已选中,我知道它是什么)以及callOut是否实际显示(我不知道)并决定重新绘制它那会更好。但是,我还没有找到callOut检测方法,而且在这个阶段我自己尝试这样做有点不必要。

答案 10 :(得分:1)

史蒂夫施的回应告诉我,必须从mapViewDidFinishLoadingMap方法调用selectAnnotation。不幸的是我不能投票,但我想在这里说谢谢。

答案 11 :(得分:0)

只需添加[mapView selectAnnotation:point animated:YES];

答案 12 :(得分:-1)

重置注释也会将标注带到前面。

    [mapView removeAnnotation: currentMarker];
    [mapView addAnnotation:currentMarker];