Требуются: как надежно и последовательно выбрать аннотацию MKMapView - PullRequest
30 голосов
/ 10 августа 2009

После вызова MKMapView setCenterCoordinate: animated: метод (без анимации) я хотел бы вызвать selectAnnotation: animated: (с анимацией) так что аннотация выскакивает из недавно центрированной канцелярской кнопки.

Пока я просто наблюдаю за mapViewDidFinishLoadingMap: и затем выбираю аннотацию. Однако это проблематично. Например, этот метод не вызывается, когда нет необходимости загружать дополнительные данные карты. В этих случаях моя аннотация не выбрана. :(

Очень хорошо. Я мог бы назвать это сразу после установки центральной координаты. Ах, но в этом случае возможно, что - это картографические данные для загрузки (но он еще не закончил загрузку). Я рискнул бы назвать это слишком рано, потому что анимация в лучшем случае стала пятнистой.

Таким образом, если я правильно понимаю, не нужно знать, видима ли моя координата, поскольку можно отклониться почти на весь экран расстояния и загрузить новые данные карты. Скорее, это вопрос знания, нужно ли загружать новые данные карты, и последующего действия соответственно.

Есть какие-нибудь идеи о том, как этого добиться или как (надежно) выбрать аннотацию после повторного центрирования представления карты по координате, в которой эта аннотация проживает?

Подсказки оценены - спасибо!

Ответы [ 7 ]

36 голосов
/ 16 февраля 2010

Я столкнулся с той же проблемой, но нашел то, что кажется надежным и разумным решением:

  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];
    }
    

Кажется, что selectAnnotation:animated: не вызывается при некоторых условиях. Сравните с MKMapView документами :

Если указанная аннотация не отображается на экране и поэтому не отображается иметь связанный вид аннотации, этот метод не имеет никакого эффекта.

7 голосов
/ 12 ноября 2010

Более последовательным способом, чем использование фиксированного тайм-аута, является прослушивание обратного вызова 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];
}
5 голосов
/ 14 августа 2013

Ну, к вашему сведению, это то, что говорят доктора,

Если указанная аннотация не отображается на экране и поэтому не отображается иметь связанный вид аннотации, этот метод не имеет никакого эффекта.

Поэтому, если я хочу позвонить 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];
    }];

Это даст вам блок завершения, и вы можете использовать его для выбора аннотации.

4 голосов
/ 02 ноября 2009

Что сработало для меня, так это вызов selectAnnotation:animated: из метода mapView:didAddAnnotationViews::

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

Документация Apple на том же здесь .

Обратите внимание, что у меня была только одна аннотация на карте, поэтому [[mapView annotations] lastObject] подойдет для моих целей. Ваш пробег может отличаться.

2 голосов
/ 15 декабря 2009

У меня была похожая проблема. Я использовал 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];
}
1 голос
/ 23 октября 2012

Я нашел несколько проблем со всеми решениями, которые я нашел для своей проблемы (я хочу выбрать аннотацию, когда я добавил ее из viewDidAppear):

  1. Использование метода делегата mapView:didAddAnnotationViews:.

    Это не сработало для меня, потому что если указанная аннотация не отображается на экране и, следовательно, не имеет связанного представления аннотации, этот метод не имеет никакого эффекта.

  2. Использование метода делегата 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.

0 голосов
/ 24 августа 2009

У меня были похожие трудности, но я вообще не мог заставить этот метод работать, не говоря уже о непоследовательности.

Вот что я нашел для работы. Может быть, это будет работать для вас тоже: Как запустить просмотр выноски MKAnnotationView, не касаясь булавки?

...