Z-index of iOS MapKit user location annotation

跟風遠走 提交于 2019-11-28 17:50:36
jmcopeland

Finally got it to work using the code listed below thanks to the help from Paul Tiarks. The problem I ran into is that the MKUserLocation annotation gets added to the map first before any others, so when you add the other annotations their order appears to be random and would still end up on top of the MKUserLocation annotation. To fix this I had to move all the other annotations to the back as well as move the MKUserLocation annotation to the front.

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

Update: You may want to add the code below to ensure the blue dot is drawn on top when scrolling it off the viewable area of the map.

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

Another solution: setup annotation view layer's zPosition (annotationView.layer.zPosition) in:

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

The official answer to that thread is wrong... using zPosition is indeed the best approach and fastest vs using regionDidChangeAnimated...

else you would suffer big performance impact with many annotations on map (as every change of frame would rescan all annotations). and been testing it...

so when creating the view of the annotation (or in didAddAnnotationViews) set : self.layer.zPosition = -1; (below all others)

and as pointed out by yuf: This makes the pin cover callouts from other pins – yuf Dec 5 '13 at 20:25

i.e. the annotation view will appear below other pins.

to fix, simply reput the zPosition to 0 when you have a selection

-(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;
   ...
}

Try, getting a reference to the user location annotation (perhaps in mapView: didAddAnnotationViews:) and then bring that view to the front of the mapView after all of your annotations have been added.

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)
        }
 }

Here is a way to do it using predicates. I think it should be faster

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

Using 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]]; });
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!