通缉:如何可靠,一致地选择MKMapView注释

时间:2009-08-10 19:53:42

标签: ios mapkit mkpinannotationview

在调用 MKMapView setCenterCoordinate:animated:方法(没有动画)之后,我想调用 selectAnnotation:animated:(使用动画)以便从新居中的图钉中弹出注释。

现在,我只是观察 mapViewDidFinishLoadingMap:,然后选择注释。但是,这是有问题的。例如,当不需要加载其他地图数据时,不会调用此方法。在这些情况下,我的注释未被选中。 :(

非常好。我可以在设置中心坐标后立即调用它。啊,但在这种情况下, 可能会加载地图数据(但尚未完成加载)。我冒险过早地调用它,动画最多也会变得不稳定。

因此,如果我理解正确,那不是知道我的坐标是否可见的问题,因为它可能会偏离几乎一定距离并且必须加载新的地图数据。相反,这是一个问题,知道是否需要加载新的地图数据,然后采取相应的行动。

关于如何实现这一点的任何想法,或者在将地图视图重新定位到注释所在的坐标上之后如何以其他方式(可靠地)选择注释?

线索赞赏 - 谢谢!

7 个答案:

答案 0 :(得分:36)

我遇到了同样的问题,但发现了似乎是一个可靠而合理的解决方案:

  1. 实现委托方法mapView:didAddAnnotationViews:。当我尝试在委托方法中直接选择注释时,标注随引脚丢弃!这看起来很奇怪,所以我加了一点半的延迟。

    -(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
        [self performSelector:@selector(selectInitialAnnotation)
              withObject:nil afterDelay:0.5];
    }
    
  2. 按照您的预期选择初始注释,但调用selectAnnotation:animated;

    -(void)selectInitialAnnotation {
        [self.mapView selectAnnotation:self.initialAnnotation animated:YES];
    }
    
  3. 似乎在某些情况下不会调用selectAnnotation:animated:。与MKMapView docs比较:

      

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

答案 1 :(得分:7)

比使用固定超时更一致的方法是收听regionDidChange回调。将地图的中心坐标设置为所需的注释,并在调用regionDidChange方法时,在中心选择注释,以打开标注。

这是video我在5针之间随机运行的东西。

首先,转到注释的中心坐标。假设注释对象名为thePin

- (void)someMethod {
    [map setCenterCoordinate:thePin.coordinate animated:YES];
}

然后在regionDidChange方法中,选择此注释。

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
    [map selectAnnotation:thePin animated:YES];
}

答案 2 :(得分:5)

嗯,仅供参考,这就是文档所说的,

  

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

因此,如果我想调用setCenterCoordinate:animated:setRegion:animated:,然后我想通过调用selectAnnotation:animated:来选择注释,注释将不会被选中且标注不会因为上面提到的完全相同的原因出现在文档中,所以有这样的方式,如setCenterCoordinate:animated:ComletionBlock,但它不存在......对我有用的方法如下,

 [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseInOut animations:^{
        [self.mapView setCenterCoordinate:location.coordinate animated:YES];
    } completion:^(BOOL finished) {
        [self.mapView selectAnnotation:location animated:YES];
    }];

这将为您提供一个完成块,您可以使用它来选择注释。

答案 3 :(得分:4)

对我有用的是从selectAnnotation:animated:方法调用mapView:didAddAnnotationViews:

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

同一here上的Apple文档。

请注意,我在地图上只有一个注释,所以[[mapView annotations] lastObject]对我来说没问题。您的里程可能会有所不同。

答案 4 :(得分:2)

我遇到了类似的问题。我使用默认的MKPinAnnotationView和animatesDrop:YES。在我将注释添加到MKMapView之后,我这样做了:

[mapView selectAnnotation:[mapView.annotations objectAtIndex:1] animated:YES]

在我的程序的逻辑中,应该选择最近的注释。这不起作用。我想出了原因:由于引脚放下动画,注释视图在此选择调用时不在屏幕上。所以我所做的就是设置一个计时器,以便在一秒钟之后选择注释。这是一个黑客,但它的工作原理。我不确定它是否适用于所有情况,例如3G和3G。最好找出合适的回调函数。

selectTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self
               selector:@selector(selectClosestAnnotation) userInfo:nil
               repeats:NO];

- (void)selectClosestAnnotation {
    [mapView selectAnnotation:[mapView.annotations objectAtIndex:1]
             animated:YES];
}

答案 5 :(得分:1)

我发现我遇到问题的所有解决方案都存在一些问题(我想在viewDidAppear中添加注释时选择注释):

  1. 使用mapView:didAddAnnotationViews:委托方法。

    这对我不起作用,因为如果指定的注释不在屏幕上,因此没有关联的注释视图,则此方法无效。

  2. 使用mapViewDidFinishLoadingMap:委托方法。

    这对我来说不起作用,因为现在缓存了地图,所以这个方法只在第一次被调用一次。

  3. 解决方案:

    约翰布莱克本非常接近但没有mapView:didAddAnnotationViews:方法。在添加注释之前,我只是调用自己的selectAnnotation:方法,但是有一个延迟:

    [self.mapView addAnnotation:ann];
    [self performSelector:@selector(selectAnnotation:) withObject:ann afterDelay:0.5];
    

    这就是我在selectAnnotation:方法中所做的:

    - (void)selectAnnotation:(id < MKAnnotation >)annotation
    {
       [self.mapView selectAnnotation:annotation animated:YES];
    }
    

    在两部iPhone 3GS(iOS 5和6)和一部iPhone 5上进行了测试。

答案 6 :(得分:0)

我遇到了类似的困难,但实际上根本无法让这种方法起作用,更不用说了。

这是我发现的工作方式。也许它也适合你: How to trigger MKAnnotationView's callout view without touching the pin?