2011-08-22 72 views
31

我需要在所有其他注释之上绘制当前用户注释(蓝点)。现在它在我的其他注释下被绘制并隐藏起来。我想调整这个注解视图的Z-index(蓝点)并将它带到最高点,有谁知道如何?iOS MapKit用户位置注释的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:????]; 
     } 
    } 
} 

回答

34

感谢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]; 
    } 
    } 
} 
+0

这个解决方案对我来说似乎并不可靠。如果我拖动地图使其偏离屏幕并返回到地图,蓝色地点点就会在我的自定义注释下面结束,大概是因为地图视图会用原始布局重新绘制视图。 –

+1

@DanJ然后使用' - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated'中的相同逻辑并通过mapView.annotations循环并找到'[mapView viewForAnnotation:annotation]' – jmcopeland

+1

好点,解决问题,尽管我发现将regionDidChangeAnimated中的代码放在比regionWillChangeAnimated更可靠的代码中。我会更新您的答案以包含额外的代码。 FTR,当使用大量注释时,会有轻微的性能问题,因为ChangeAnimated方法应尽可能轻量化。 –

2

尝试,让用户位置注释(也许在mapView: didAddAnnotationViews:)的引用,然后把该视图的MapView前面所有的注释已被添加之后。

+0

我还没有想出得到它的一个把手,因为你可以”吨测试它的类MKUserLocationView和我的所有其他注释是普通的MKAnnotationView对象和MKUserLocationView是MKAnnotationView的子类...我正在考虑将我的注释切换到覆盖,以便我可以管理这些的zindex并保持它们分开来自用户位置注释。任何其他想法? – jmcopeland

+1

您应该能够测试注解属性的类以查看它是否为MKUserLocation并将其作为用户位置视图保留。 –

+0

感谢上面的你的建议,我已经能够获得MKUserLocationView的位置,但是我没有能够把它推进。我用bringSubviewToFront尝试过各种咒语:但我没有尝试过。有什么想法吗? – jmcopeland

0

这是一种使用谓词的方法。我觉得应该是更快

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

另一种解决方案: 设置注释视图层的z位置(annotationView.layer.zPosition)中:

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

+0

这个解决方案对我来说是最可靠的。 –

+0

这比管理子视图的顺序要容易得多。 –

+3

这使得来自其他针脚的封面标注 – yuf

0

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

官方答案到那个线程是错误的...使用zPosition确实是使用regionDidChan最好的方法和最快的geAnimated ...

否则,您会遭受地图上许多注释带来的巨大性能影响(因为每次更改帧都会重新扫描所有注释)。并已测试它...

所以当创建注释的视图(或在didAddAnnotationViews)设置: self.layer.zPosition = -1; (下面的所有其他)

并且如yuf指出: 这使得销罩标注从其他引脚 - yuf 12月5日'13 20:25

即注解视图下方会出现其他引脚。

修复,只需reput z位置为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; 
    ... 
} 
+0

当你只需要管理视觉效果时,这种解决方案非常好,但是如果你也需要处理点击/触摸的优先级,它就不起作用了(你点击一个看起来在别人之上的针(因为zPosition是0),但实际上你点击下面的一个引脚)。 – jptsetung

+0

这是苹果的标准pin行为...更改zlocation并不妨碍这...但这是另一个问题。为了不弹出,你应该在自定义注释中使用self.canShowCallout = NO – altagir

1

斯威夫特,当你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) 
     } 
}