iOS MapKit用户位置标注的z索引。

时间:2022-11-15 20:01:26

I need to draw the current user annotation (the blue dot) on top of all other annotations. Right now it is getting drawn underneath my other annotations and getting hidden. I'd like to adjust the z-index of this annotation view (the blue dot) and bring it to the top, does anyone know how?

我需要在所有其他注释的上面绘制当前用户注释(蓝点)。现在它在我的其他注解下面被隐藏起来。我想调整这个annotation视图的z索引(蓝色的点)并把它带到顶部,有人知道怎么做吗?

Update: So I can now get a handle on the MKUserLocationView, but how do I bring it forward?

更新:所以我现在可以在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 个解决方案

#1


34  

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.

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

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

#2


25  

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

另一个解决方案:设置注释视图层的zPosition(注释视图.layer.zPosition):

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

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)视图;

#3


9  

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

官方对这个问题的回答是错误的……使用zPosition确实是最好的方法,而且使用区域转换动画的速度最快……

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)

因此,当创建注释(或didaddannotationview)的视图时,设置:self。layer。zPosition = 1;(以下所有人)

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

正如yuf所指出的:这使得大头针覆盖了其他引脚的标注——yuf Dec 5 '13在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

要修复,只需在选择时将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


2  

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.

尝试获取对用户位置注释的引用(可能是在mapView: didAddAnnotationViews:),然后在添加了所有注释之后将该视图带到mapView的前面。

#5


1  

Swift 3:

斯威夫特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


0  

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

#7


0  

Using Underscore.m

使用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]]; });

#1


34  

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.

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

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

#2


25  

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

另一个解决方案:设置注释视图层的zPosition(注释视图.layer.zPosition):

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

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)视图;

#3


9  

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

官方对这个问题的回答是错误的……使用zPosition确实是最好的方法,而且使用区域转换动画的速度最快……

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)

因此,当创建注释(或didaddannotationview)的视图时,设置:self。layer。zPosition = 1;(以下所有人)

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

正如yuf所指出的:这使得大头针覆盖了其他引脚的标注——yuf Dec 5 '13在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

要修复,只需在选择时将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


2  

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.

尝试获取对用户位置注释的引用(可能是在mapView: didAddAnnotationViews:),然后在添加了所有注释之后将该视图带到mapView的前面。

#5


1  

Swift 3:

斯威夫特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


0  

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

#7


0  

Using Underscore.m

使用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]]; });