Желанный:Как надежно и последовательно выбрать аннотацию MKMapView
-
12-09-2019 - |
Вопрос
После звонка MKMapView (Просмотр MKMapView)'s setCenterCoordinate:анимированный: метод (без анимации), я бы хотел вызвать Выберите аннотацию: анимированную: (с анимацией) так, чтобы аннотация выскакивала из только что отцентрированной кнопки.
На данный момент я просто наблюдаю за mapViewDidFinishLoadingMap - просмотрданной загрузочной карты: а затем выберите аннотацию.Однако это проблематично.Например, этот метод не вызывается, когда нет необходимости загружать дополнительные картографические данные.В этих случаях моя аннотация не выбрана. :(
Очень хорошо.Вместо этого я мог бы вызвать это сразу после установки центральной координаты.Ах, но в таком случае вполне возможно, что там является картографические данные для загрузки (но загрузка еще не завершена).Я бы рискнул назвать это слишком рано, поскольку анимация в лучшем случае становится пятнистой.
Таким образом, если я правильно понимаю, дело не в том, чтобы знать, видна ли моя координата, поскольку можно отклониться почти на приличное расстояние и придется загружать новые картографические данные.Скорее, все дело в том, чтобы знать, нужно ли загружать новые картографические данные, а затем действовать соответствующим образом.
Есть идеи о том, как это сделать или как иным образом (надежно) выбрать аннотацию после повторного центрирования вида карты по координате, в которой находится эта аннотация?
Подсказки оценены - спасибо!
Решение
Я столкнулся с той же проблемой, но нашел то, что кажется надежным и разумным решением:
Реализуйте метод делегирования MapView:didAddAnnotationViews:.Когда я попытался выбрать аннотацию непосредственно в методе делегирования, выноска была удалена вместе с pin-кодом!Это выглядело странно, поэтому я добавил небольшую задержку в полсекунды.
-(void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views { [self performSelector:@selector(selectInitialAnnotation) withObject:nil afterDelay:0.5]; }
Выберите начальную аннотацию, как и следовало ожидать, но вызовите selectAnnotation:animated;
-(void)selectInitialAnnotation { [self.mapView selectAnnotation:self.initialAnnotation animated:YES]; }
Кажется , что selectAnnotation:animated:
не вызывается при некоторых условиях.Сравнить с Документы MKMapView:
Если указанный аннотация не на экране, а, следовательно, не иметь соответствующий вид Примечания, этот метод не имеет никакого эффекта.
Другие советы
Более последовательный способ, чем использование фиксированного тайм-аута, — это прослушивание regionDidChange
перезвонить.Установите центральную координату карты на нужную аннотацию, а при вызове метода RegionDidChange выберите аннотацию в центре, чтобы открыть выноску.
Вот немного видео Я взял, что эта штука случайным образом работает между 5 контактами.
Сначала перейдите к центральной координате аннотации.Допустим, объект аннотации называется thePin
.
- (void)someMethod {
[map setCenterCoordinate:thePin.coordinate animated:YES];
}
Затем в regionDidChange
метод, выберите эту аннотацию.
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
[map selectAnnotation:thePin animated:YES];
}
Ну, просто К твоему сведению, это то, что говорят документы,
Если указанный аннотация не на экране, а, следовательно, не иметь соответствующий вид Примечания, этот метод не имеет никакого эффекта.
Так что, если я захочу позвонить 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];
}];
Это даст вам блок завершения, и вы сможете использовать его для выбора аннотации.
Что мне помогло, так это звонок selectAnnotation:animated:
из mapView:didAddAnnotationViews:
метод:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;
{
[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
}
Документация Apple по этому же вопросу здесь.
Обратите внимание, что у меня на карте была только одна аннотация, поэтому [[mapView annotations] lastObject]
было хорошо для моих целей.Ваш пробег может отличаться.
У меня была аналогичная проблема.Я использовал MKPinAnnotationView по умолчанию с animatesDrop:YES.После добавления аннотаций в MKMapView я делал следующее:
[mapView selectAnnotation:[mapView.annotations objectAtIndex:1] animated:YES]
который по логике моей программы должен выбрать ближайшую аннотацию.Это не работало.Я понял причину:вид аннотации не был на экране во время этого вызова выбора из-за анимации падения булавки.Поэтому все, что я сделал, это установил таймер, чтобы выбрать аннотацию секундой позже.Это хак, но он работает.Я не уверен, что это будет работать в любой ситуации, например, в сети 3G или в сети 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];
}
Я обнаружил несколько проблем со всеми решениями, которые я видел для своей проблемы (я хочу выбрать аннотацию, когда добавлял ее из viewDidAppear):
Используя
mapView:didAddAnnotationViews:
метод делегата.У меня это не сработало, поскольку если указанная аннотация не отображается на экране и, следовательно, не имеет связанного представления аннотации, этот метод не имеет никакого эффекта.
Используя
mapViewDidFinishLoadingMap:
метод делегата.У меня это тоже не сработало, потому что карта теперь кэшируется, поэтому метод вызывается только один раз, в первый раз.
Решение:
Джон Блэкберн был очень близок, но без 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.
У меня были похожие трудности, но на самом деле я вообще не смог заставить этот метод работать, не говоря уже о непоследовательной работе.
Вот что я нашел для работы.Возможно, это подойдет и вам:Как вызвать представление выноски MKAnnotationView, не касаясь булавки?