swift - Swift - MapView 重复注释
问题描述
我正在从 FireStore 查询数据并在 MapView 上显示元素,使用能够对数据进行分页的光标。
这是我的自定义注释类:
final class PostAnnotation: NSObject, MKAnnotation {
var title: String?
var coordinate: CLLocationCoordinate2D
var username: String
var post: PostModel
var subtitle: String?
init(address: PostPlaceMark) {
self.title = address.title
self.coordinate = address.coordinate
self.username = address.username
self.post = address.post
self.subtitle = address.subTitle
}
}
我点击了一个按钮来加载更多数据,出于测试目的,我的数据池非常小,大约只有 7-10 个元素。但是,每当我获取/刷新数据时,我总是会得到前一组注释的副本。
例如,当我的 MapView 第一次加载时,我有一批批注,点击刷新按钮,我有一批批注 1 和一批批注 2,但也有一批批注 1 的副本。再次点击刷新,我有一批批注 x 3、batch of annotations 2 x 2 和所有数据的一个实例,属于batch of annotations 3。
我已经设法找出问题所在,但我有两个极端:
- 一个我不断收到重复的注释
- 二 前一批被删除
我这样做的原因是为了对抗可能/可能有围绕特定视图的许多注释的事实。我仅限于问题和潜在解决方案可能存在的地方。
private static func annotationsByDistributingAnnotationsContestingACoordinate(annotations: [PostAnnotation], constructNewAnnotationWithClosure ctor: annotationRelocator) -> [PostAnnotation] {
var newAnnotations = [PostAnnotation]()
let contestedCoordinates = annotations.map{ $0.coordinate }
let newCoordinates = coordinatesByDistributingCoordinates(coordinates: contestedCoordinates)
newAnnotations.removeAll()
for (i, annotation) in annotations.enumerated() {
let newCoordinate = newCoordinates[i]
let newPost = annotation.post
let newAnnotation = ctor(annotation, newCoordinate, newPost)
print(newAnnotation.post.location)
newAnnotations.forEach { (naac) in
annotations.forEach { (element) in
if newAnnotations.contains(where: {$0.post.postID == naac.post.postID}) {
let index = newAnnotations.firstIndex{$0.post.postID == naac.post.postID}
// newAnnotations.remove(at: index!)
print("removed")
// newAnnotations.removeAll(where: {$0.post.postID == naac.post.postID})
}
}
}
newAnnotations.append(newAnnotation)
}
let withoutDuplicates = Array(Set(newAnnotations))
return withoutDuplicates
}
我可以检测元素是否已经在数组中,但是,删除它,即使是 firstIndex 也会导致我完全丢失注释。
这就是我添加/更新注释的方式,以防您想知道:
private func updateAnnotations(from mapView: MKMapView) {
let annotations = self.address.map(PostAnnotation.init)
let newAnnotations = ContestedAnnotationTool.annotationsByDistributingAnnotations(annotations: annotations) {
(oldAnn: MKAnnotation, newCoordinate:CLLocationCoordinate2D, post: PostModel) -> (PostAnnotation) in
PostAnnotation(address: PostPlaceMark.init(post: post, coordinate: newCoordinate, title: "\(post.manufacturer) \(post.model)", username: post.username, subTitle: "£\(post.price)"))
}
mapView.removeAnnotations(mapView.annotations)
mapView.addAnnotations(newAnnotations)
}
解决方案
推荐阅读
- sorbet - 如何在不降级印记的情况下使用 `srb rbiSuggest-typed`?
- java - 如何将从 api 获取的 json 数据放入反应状态数组中?
- java - 如何从第二行开始读取 CSV 文件
- ios - 尝试在 macOS 上使用 CMake 并发生这种情况:CMake Error at ipsw-patch/CMakeLists.txt:19 (message): libcrypto is required for ipsw
- sql - 如何在 Athena 的联接中修复 select 语句?
- angular - Angular:在 PrimeNG RowGroup 表中选择嵌套行
- sharepoint-online - 在 Power Automate 中,我使用 Patch 方法向 SharePoint 发送 HTTP 请求未将 SharePoint 列表上的字段更新为空
- sql - 如何在不手动输入 R 的情况下为多列指定 sqlSave() 的 vartype?
- google-sheets - 展平跳过空白单元格而不使用 UNIQUE
- azure - azure Application Insights 中没有 performanceCounters/Requests 数据