iOS MapKit用户位置注释的Z-index

jmc*_*and 32 objective-c mapkit ios

我需要在所有其他注释之上绘制当前用户注释(蓝点).现在它正在我的其他注释下面被隐藏起来.我想调整此注释视图的z-index(蓝点)并将其置于顶部,有人知道如何吗?

更新: 所以我现在可以处理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:????];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

jmc*_*and 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];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:您可能需要添加下面的代码,以确保在将其从地图的可视区域滚动时在顶部绘制蓝点.

- (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];
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


hrc*_*hen 25

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

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

  • 这使得引脚盖上的标注来自其他引脚 (3认同)

alt*_*gir 9

该线程的官方答案是错误的......使用zPosition确实是最好的方法,使用regionDidChangeAnimated是最快的...

否则你会因地图上的许多注释而遭受巨大的性能影响(因为每次帧的更改都会重新扫描所有注释).并一直在测试......

所以在创建注释视图时(或在didAddAnnotationViews中)设置:self.layer.zPosition = -1; (低于所有其他人)

并且正如yuf所指出的:这使得引脚盖上来自其他引脚的标注 - yuf 12年5月5日在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;
   ...
}
Run Code Online (Sandbox Code Playgroud)


Jon*_*gel 5

iOS 14 更新

我知道这是一个旧帖子,但这个问题仍然适用,当你将它输入到你最喜欢的搜索引擎时,你最终会来到这里。

从 iOS 14 开始,ApplezPriorityMKAnnotationView. 您可以使用它使用预定义的常量或浮点数为您的注释设置 z-index 。此外,Apple 最终可以为我们自己创建用户位置的视图,并MKUserLocationView作为MKAnnotationView.

从文档中MKUserLocationView

如果要指定额外的配置,比如zPriority,直接创建这个注解视图。要显示注释视图,请从 返回实例mapView(_:viewFor:)

以下代码片段显示了如何完成此操作(将代码添加到您的MKMapViewDelegate):

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    
    // Alter the MKUserLocationView (iOS 14+)
    if #available(iOS 14.0, *), annotation is MKUserLocation {
        
        // Try to reuse the existing view that we create below
        let reuseIdentifier = "userLocation"
        if let existingView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier) {
            return existingView
        }
        let view = MKUserLocationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
        
        view.zPriority = .max   // Show user location above other annotations
        view.isEnabled = false  // Ignore touch events and do not show callout
        
        return view
    }
    
    // Create views for other annotations or return nil to use the default representation
    
    return nil
}
Run Code Online (Sandbox Code Playgroud)

请注意,默认情况下,用户位置注释在点击时会显示一个标注。既然用户位置覆盖了您的其他注释,您可能想要禁用它,这是通过在代码中设置.isEnabled为 来完成的false