有没有办法确保在 MapKit 中完成聚类过程?

问题描述

我有一个带有显示设备的地图部分的应用。在某些情况下,设备可能彼此非常接近,甚至具有完全相同的坐标。为了显示它,我使用 MapKit 中的认聚类机制。

func mapView(_ mapView: MKMapView,clusterannotationForMemberAnnotations memberAnnotations: [MKAnnotation]) -> MKClusterannotation {
    return MKClusterannotation(memberAnnotations: memberAnnotations)
}

用户点击集群注释时,应用程序应该最大程度地放大,然后在地图上仍然存在集群的情况下(成员注释太近而无法单独呈现)打开描述集群对象的自定义视图。

为了实现这一点,我有几个自定义函数,它们的实现只包含标准调用 setRegion 或 setVisibleMapRect。

setRegionCovering(_ annotations: [MKAnnotation],on mapView: MKMapView)
getZoom(delta: CGFloat)
func mapView(_ mapView: MKMapView,didSelect view: MKAnnotationView) {
    if let annot = view.annotation as? MKClusterannotation {
        let clusteredAnnotations = annot.memberAnnotations as? [CustomAnnotation] ?? []
        let currentZoom = mapView.getZoom(delta: CGFloat(mapView.region.span.longitudeDelta))
        guard currentZoom == self.maxZoom else {
             self.setRegionCovering(clusteredAnnotations,on: mapView)
             return
        }
        self.delegate?.drawCluster(annotations: clusteredAnnotations)
    }
}

为了在放大后调用集群,我使用 regionDidChangeAnimated 方法

func mapView(_ mapView: MKMapView,regionDidChangeAnimated animated: Bool) {
    if let activeCluster = mapView.selectedAnnotations.first(where: { $0.isKind(of: MKClusterannotation.self)}) as? MKClusterannotation {
        self.delegate?.drawCluster(annotations: activeCluster.memberAnnotations as? [CustomAnnotation] ?? [])
    }
}

到目前为止一切都按预期工作,除了一件事 - 在相机焦点(区域)完成后调用 regionDidChangeAnimated。但是,我发现在某些情况下,在调用 regionDidChangeAnimated 后聚类会继续进行。因此,在极少数情况下,用户在点击集群注释后会看到集群内容的短暂“闪烁”,然后它会像旧集群一样消失,取而代之的是较小的集群或成员注释。


之前我曾尝试通过在 animate 函数中嵌入地图缩放操作来完成相同的操作,以便在完成时处理集群视图打开。

MKMapView.animate(withDuration: 1.0,animations: {},completion: { _ in })

但发现完成在 regionDidChangeAnimated 之前触发并且更不准确。后来我还发现 Apple 在使用地图时强烈反对完成。


任何想法我做错了什么或我该如何解决这个问题?

解决方法

您可以尝试实现 mapViewDidFinishRenderingMap(_:fullyRendered:),看看它是否比 mapView(_:regionDidChangeAnimated:) 实现提供更好的结果。

来自文档 -

这个方法让你知道地图视图何时完成渲染所有当前可见的瓦片,以尽其所能。无论是否成功渲染了所有图块,都会调用此方法。如果加载一个或多个图块时出现错误,导致地图视图无法呈现它们,则 fullyRendered 参数设置为 false

这不能为您的问题提供可靠的答案。这可能比您目前的情况有所改善。