Проблема с вызовом 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 и новым или скорость вашего интернет-соединения.
Я решил сделать вызов с - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
, поскольку он гарантирует, что аннотация фактически отображается на экране (при условии, что вы установили регион MapView в качестве координаты аннотации), потому что это событие срабатывает после setRegion
(и его анимация) закончена. Однако 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
, не вызовет сноску.