处理重叠的MKAnnotationView(s)

时间:2014-12-26 10:49:10

标签: ios mkmapview mkannotation mkannotationview

我们如何确保将注释视图放置在地图上的指定顺序/位置?

我有一个案例,其中一个地址可以有多个注释(在另一个之上)。例如,Pin编号1,2,3和4放置在相同的地理位置。当地图加载时,我希望Pin#1位于顶部,但是无法确保Pin#1始终可见(在顶部)。

环顾四周,我找到了以下解决方案,但这些都没有对我有用。

1)。按照您希望的顺序将注释添加到地图中。

根据我的经验,它不起作用!根据我的经验,使用addAnnotations:一起添加注释或逐个添加注释会产生相同的结果。注释视图的顺序仍然是随机的。

[self.mapView addAnnotations:allAnnotations];

生成与:

相同的结果
for (MyCustomAnnotation *annotation in allAnnotations) {
    [self.mapView addAnnotation:annotation];
}

2)。使用bringSubviewToFront或sendSubviewToBack指定所有注释的顺序。

根据我的经验,它不起作用!例如,以下代码不会生成所需的结果:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
    // .tag associated with each view specifies the order/hierarchy of annotation views
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"tag" ascending:YES];
    NSArray *orderedAnnotationViews = [views sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

    for (MKAnnotationView *annotationView in orderedAnnotationViews) {
        [mapView sendSubviewToBack:annotationView];
    }
}

第3)。使用annotationView.layer.zPosition指定所有注释的确切顺序。

考虑4个引脚重叠的情况,例如引脚1,2,3和4.这种方法的问题是,点击特定的注释引脚或以编程方式选择它不会将它带到前面。 zPosition是绝对的。您可以在每次选择引脚时更改它,但这并不理想。

  

zPosition属性指定图层的z轴组件   位置。 zPosition旨在用于设置视觉效果   层相对于其兄弟层的位置。它不应该   用于指定图层兄弟的顺序,而是重新排序图层   在子层数组中。

思想?

2 个答案:

答案 0 :(得分:4)

我最终使用zPosition

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"tag" ascending:NO];
    NSArray *sortedViews = [views sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];

    // Set zPosition
    for (MKAnnotationView *annotationView in sortedViews) {
        annotationView.layer.zPosition = ++_zPositionForAnnotationViews;
    }

    // Do whatever
    // . . .
}

- (void)mapView:(MKMapView *)aMapView didSelectAnnotationView:(MKAnnotationView *)view {
    NSLog(@"The annotation tapped is: %@", view.annotation.title);

    // Ignore tap on user location
    if ([view.annotation isKindOfClass:[MKUserLocation class]]) {
        return;
    }

    // Update zPosition (to bring it to front)
    view.layer.zPosition = ++_zPositionForAnnotationViews;

    // Do whatever
    // . . .
}

_zPositionForAnnotationViews是一个类变量。

答案 1 :(得分:0)

iOS 11在这里打破了给定的解决方案(即使用zPosition)。要恢复使用zPosition的功能,请参阅以下答案: https://stackoverflow.com/a/48453515/320737