Z-индекс аннотации местоположения пользователя iOS MapKit - PullRequest
32 голосов
/ 22 августа 2011

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

Обновление: Так что теперь я могу получить дескриптор 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:????];
        }
    }
}

Ответы [ 7 ]

34 голосов
/ 29 августа 2011

Наконец-то начал работать, используя код, указанный ниже, благодаря помощи Пола Тиаркс .Проблема, с которой я столкнулся, заключается в том, что аннотация 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];
    }
  }
}
25 голосов
/ 03 мая 2013

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

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

9 голосов
/ 23 сентября 2014

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

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

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

и как указано yuf: Это делает выноски на крышки контактов с других контактов - yuf 5 декабря 13 в 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;
   ...
}
2 голосов
/ 22 августа 2011

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

1 голос
/ 13 февраля 2017

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)
        }
 }
0 голосов
/ 15 июля 2014

Использование 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]]; });
0 голосов
/ 07 марта 2013

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

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];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...