从- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView 调用selectAnnotation 的问题在于,顾名思义,此事件仅在您的 MapView 初始加载时触发,因此如果您在之后添加注解,您将无法触发注解的标注MapView 已完成加载。
从- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views 调用它的问题是,当调用selectAnnotation 时,您的注释可能不在屏幕上,这将导致它不起作用。即使您在添加注释之前将 MapView 的区域居中到注释的坐标,设置 MapView 区域所需的轻微延迟也足以在屏幕上显示注释之前调用 selectAnnotation,特别是如果您为 @987654326 设置动画@。
有些人通过在延迟后致电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 连接速度。
我决定改为从- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 进行调用,因为它确保注释实际上在屏幕上(假设您将 MapView 的区域设置为注释的坐标),因为此事件是在 @ 之后触发的987654330@(及其动画)已完成。然而,regionDidChangeAnimated 会在您的 MapView 区域发生变化时触发,包括当用户只是在地图上平移时,因此您必须确保您有一个条件来正确识别何时是触发注释标注的正确时间。
我是这样做的:
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 中的区域设置之外没有任何区域设置会触发标注。