Я хотел сделать то же самое и закончил делать следующее.
Предостережение перед тем, как я начну: я знаю, что решение довольно уродливое! ... но эй, это работает.
Примечание: Я нацеливание IOS 9, но он должен работать на предыдущие версии прошивки:
Хорошо, здесь мы идем:
- Во-первых, создать новое свойство в контроллере представления, например, :
@property(nonatomic, assign, getter=isPinCenteringOngoing) BOOL pinCenteringOngoing;
- в
mapView:viewForAnnotation:
установить canShowCallout
в NO
для annotationViews
в mapView:didSelectAnnotationView:
сделать следующее:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
if([view isKindOfClass:$YOURANNOTATIONVIEWCLASS$.class])
{
if(!self.isPinCenteringOngoing)
{
self.pinCenteringOngoing = YES;
[self centerMapOnSelectedAnnotationView:($YOURANNOTATIONVIEWCLASS$ *)view];
}
else
{
self.pinCenteringOngoing = NO;
}
}
}
в mapView:didDeselectAnnotationView:
сделать следующее:
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
if([view isKindOfClass:$YOURANNOTATIONVIEWCLASS$.class])
{
if(!self.isPinCenteringOngoing)
{
view.canShowCallout = NO;
}
}
}
и, наконец, создать новый метод, который делает фактическую работу:
- (void)centerMapOnSelectedAnnotationView:($YOURANNOTATIONVIEWCLASS$ *)view
{
// Center map
CGPoint annotationCenter = CGPointMake(CGRectGetMidX(view.frame), CGRectGetMidY(view.frame));
CLLocationCoordinate2D newCenter = [self.mapView convertPoint:annotationCenter toCoordinateFromView:view.superview];
[self.mapView setCenterCoordinate:newCenter animated:YES];
// Allow callout to be shown
view.canShowCallout = YES;
// Deselect and then select the annotation so the callout is actually displayed
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void)
{
[self.mapView deselectAnnotation:view.annotation animated:NO];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^(void)
{
[self.mapView selectAnnotation:view.annotation animated:NO];
});
});
}
Чтобы завершить мой ответ, здесь это текстовое объяснение того, что я делаю в приведенном выше коде и почему я это делаю:
- То, что я хочу, это аннотация, которая будет центрирована на экране, и выносок, который будет центрирован над ним.
- Что я получаю по умолчанию является:
- При выборе аннотации, карта открывает выноски, и при необходимости корректирует карту таким образом, выноска помещается на экране. Ни в коем случае эта стандартная реализация не гарантирует, что выноска «центрирована» над аннотацией.
- Поцентрирование карты с помощью setCenterCoordinate :, аннотация направлена по центру.
- Теперь два предыдущих совмещенных точки могут привести к тому, что выноска будет «обрезана», поскольку аннотация центрирована на карте, но выноска не центрируется над аннотацией.
- Чтобы это исправить, я следующее:
- первым отключить выноски, который будет отображаться по умолчанию, установив canShowCallout ни к чему для каждого annotationView
- , когда пользователь выбирает аннотацию, я первый центрировать карту
- затем я позволил выноске быть показана, установкой canShowCallout ДА для выбранной аннотации
- я тогда отменить выбор, а затем снова выберите аннотацию, так выноска фактически отображается
- для того, чтобы выноски быть правильно по центру над аннотацией, мне нужно сделать Deselecting/выбор несколько запаздывает, так что карта центрирование может завершить
Я надеюсь, что мой ответ может оказаться полезным.
Вы пробовали настройку 'MKCoordinateRegion' с широтой и долготой устанавливаются таким же, как контактные, и пролет установлен независимо от текущей пяди, а затем установив свойство «center» области на местоположение булавки? – GlennRay
@GlennRay это будет просто центрировать карту на штырьке, а также только после отображения выноски, если я правильно пойму. – Ch1llb4y
Глядя на другие вопросы, подобные этому очень быстро, появляются два решения. Во-первых, вы можете использовать диспетчер, чтобы задержать появление выноски в течение нескольких секунд, дав центру время карты. Или вы можете иметь центр карты на месте x%/y% от места, где на самом деле находится контакт, чтобы уступить место выноску. – GlennRay