Желанный:Как надежно и последовательно выбрать аннотацию MKMapView

StackOverflow https://stackoverflow.com/questions/1256875

  •  12-09-2019
  •  | 
  •  

Вопрос

После звонка MKMapView (Просмотр MKMapView)'s setCenterCoordinate:анимированный: метод (без анимации), я бы хотел вызвать Выберите аннотацию: анимированную: (с анимацией) так, чтобы аннотация выскакивала из только что отцентрированной кнопки.

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

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

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

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

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

Это было полезно?

Решение

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

  1. Реализуйте метод делегирования MapView:didAddAnnotationViews:.Когда я попытался выбрать аннотацию непосредственно в методе делегирования, выноска была удалена вместе с pin-кодом!Это выглядело странно, поэтому я добавил небольшую задержку в полсекунды.

    -(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:

Если указанный аннотация не на экране, а, следовательно, не иметь соответствующий вид Примечания, этот метод не имеет никакого эффекта.

Другие советы

Более последовательный способ, чем использование фиксированного тайм-аута, — это прослушивание 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):

  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.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top