Подтвердить что ты не робот

Z-индекс аннотации местоположения iOS MapKit

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

Update: Итак, теперь я могу получить представление о MKUserLocationView, но как его перенести?

- (void) mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views {
    for (MKAnnotationView *view in views) {
        if ([[view annotation] isKindOfClass:[MKUserLocation class]]) {
            // How do I bring this view to the front of all other annotations?
            // [???? bringSubviewToFront:????];
        }
    }
}
4b9b3361

Ответ 1

Наконец, он получил работу, используя приведенный ниже код благодаря помощи Paul Tiarks. Проблема, с которой я столкнулся, заключается в том, что аннотация MKUserLocation добавляется к карте сначала перед любыми другими, поэтому, когда вы добавляете другие аннотации, их порядок выглядит случайным и все равно заканчивается поверх аннотации MKUserLocation. Чтобы исправить это, мне пришлось переместить все остальные аннотации на спину, а также перенести аннотацию MKUserLocation на передний план.

- (void) mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views 
{
    for (MKAnnotationView *view in views) 
    {
        if ([[view annotation] isKindOfClass:[MKUserLocation class]]) 
        {
            [[view superview] bringSubviewToFront:view];
        } 
        else 
        {
            [[view superview] sendSubviewToBack:view];
        }
    }
}

Обновить. Вы можете добавить код ниже, чтобы убедиться, что синяя точка рисуется сверху при прокрутке ее с видимой области карты.

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{        
  for (NSObject *annotation in [mapView annotations]) 
  {
    if ([annotation isKindOfClass:[MKUserLocation class]]) 
    {
      NSLog(@"Bring blue location dot to front");
      MKAnnotationView *view = [mapView viewForAnnotation:(MKUserLocation *)annotation];
      [[view superview] bringSubviewToFront:view];
    }
  }
}

Ответ 2

Другое решение: установка слоя представления аннотации zPosition (annotationView.layer.zPosition) в:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;

Ответ 3

Официальный ответ на этот поток неправильный... использование zPosition - действительно лучший подход и самый быстрый против использования regionDidChangeAnimated...

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

поэтому при создании представления аннотации (или в didAddAnnotationViews) установите:       self.layer.zPosition = -1; (ниже всех остальных)

и как указано yuf:  Это делает вырезывание крышки штыря из других контактов - yuf Dec 5 '13 at 20:25

то есть. вид аннотации появится ниже других контактов.

чтобы исправить, просто присвойте zPosition 0, когда у вас есть выбор

-(void) mapView:(MKMapView*)mapView didSelectAnnotationView:(MKAnnotationView*)view {
    if ([view isKindOfClass:[MyCustomAnnotationView class]])
        view.layer.zPosition = 0;
   ...
}

-(void) mapView:(MKMapView*)mapView didDeselectAnnotationView:(MKAnnotationView*)view {
    if ([view isKindOfClass:[MyCustomAnnotationView class]])
        view.layer.zPosition = -1;
   ...
}

Ответ 4

Попробуйте получить ссылку на аннотацию местоположения пользователя (возможно, в mapView: didAddAnnotationViews:), а затем довести это представление до начала mapView после того, как были добавлены ваши аннотации.

Ответ 5

Swift 3:

internal func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) {
        for annotationView in views {
            if annotationView.annotation is MKUserLocation {
                annotationView.bringSubview(toFront: view)
                return
            }
            annotationView.sendSubview(toBack: view)
        }
 }

Ответ 6

Вот как это сделать, используя предикаты. Я думаю, что это должно быть быстрее

NSPredicate *userLocationPredicate = [NSPredicate predicateWithFormat:@"class == %@", [MKUserLocation class]];
NSArray* userLocation = [[self.mapView annotations] filteredArrayUsingPredicate:userLocationPredicate];

if([userLocation count]) {
    NSLog(@"Bring blue location dot to front");
    MKAnnotationView *view = [self.mapView viewForAnnotation:(MKUserLocation *)[userLocation objectAtIndex:0]];
    [[view superview] bringSubviewToFront:view];
}

Ответ 7

Использование Underscore.m

_.array(mapView.annotations).
    filter(^ BOOL (id<MKAnnotation> annotation) { return [annotation 
isKindOfClass:[MKUserLocation class]]; })
    .each(^ (id<MKAnnotation> annotation) { [[[mapView 
viewForAnnotation:annotation] superview] bringSubviewToFront:[mapView 
viewForAnnotation:annotation]]; });

Ответ 8

Я решил эту проблему путем реализации этого метода здесь.
Изображение ниже показывает результат сейчас.
Код, реализованный с помощью Swift 5.0 на iOS 12.3.1. Дайте мне знать, если вам нужны примеры кода.

enter image description here