有一个名为“ClusterAnnotationView”的自定义 MKClusterAnnotation。当我没有预料到时,它会在“assertionFailure”消息中失败。
这是代码:
//MARK: CLUSTER ANNOTATION
final class ClusterAnnotationView: MKAnnotationView {
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
collisionMode = .circle
displayPriority = .defaultHigh
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var annotation: MKAnnotation? {
didSet {
guard let annotation = annotation as? MKClusterAnnotation else {
print(annotation)
assertionFailure("Using ClusterAnnotationView with wrong annotation type")
return
}
self.image = image(count: annotation.memberAnnotations.count)
}
}
private func image(count: Int) -> UIImage {
let bounds = CGRect(origin: .zero, size: CGSize(width: 40, height: 40))
let renderer = UIGraphicsImageRenderer(bounds: bounds)
return renderer.image { _ in
//background
Definitions.Colors.Water.setFill()
UIBezierPath(ovalIn: bounds).fill()
// Fill inner circle with white color inset so background shows as border
UIColor.white.setFill()
UIBezierPath(ovalIn: bounds.insetBy(dx: 4, dy: 4)).fill()
// Finally draw count text vertically and horizontally centered
let attributes: [NSAttributedString.Key: Any] = [
.foregroundColor: UIColor.black,
.font: UIFont.boldSystemFont(ofSize: 14)
]
let text = "\(count)"
let size = text.size(withAttributes: attributes)
let origin = CGPoint(x: bounds.midX - size.width / 2, y: bounds.midY - size.height / 2)
let rect = CGRect(origin: origin, size: size)
text.draw(in: rect, withAttributes: attributes)
}
}
}
现在,如果我注释掉“assertionFailure(“使用带有错误注释类型的 ClusterAnnotationView”)”,它将显示具有正确编号的集群注释。注释的打印全部打印nil。
查看了 Apple 上关于 Clustering 的文档以及其他一些文档。很多例子都表明它就像我有它一样。
已注册
mapView.register(ClusterAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier)
它的代表就像这样
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
switch annotation {
case is MapAnnotation:
let eventAnnotation = MapAnnotationView(annotation: annotation, reuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
eventAnnotation.delegate = self
return eventAnnotation
case is MKClusterAnnotation:
//return ClusterAnnotationView(annotation: annotation, reuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier)
return mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier, for: annotation)
default:
return nil
}
}
我已经尝试了委托中的返回和类的返回,并且只是出队,结果相同。
发生了一些奇怪的事情,因为聚集注释导致地图功能非常滞后,并且它可能与我所看到的问题有关。
有人有任何见解吗?
谢谢
func mapView
至少有一处错误:
对于您要调用的每个不同的
MKAnnotationView
子类,您需要一个不同的reuseIdentifier。这里发生的事情是随机的:
如果首先调用
mapView.dequeueReusableAnnotationView
,则返回 nil。
nil 意味着return mapView.dequeueReusableAnnotationView
启动并创建一个
mapView.register...
实例,一切正常。那就是你看到数字的时候。一旦您创建了多个ClusterAnnotationView
,第一个在不再显示时就会被丢弃:
既然你用同样的MapAnnotationView
,
reuseIdentifier
将返回类型为
return mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier, for: annotation)
的对象。
此外,使用MapAnnotationView
后,您应该设置出队的
dequeue...
子类对象的注释。这是您用于每种不同注释类型的模式:
MKMarkerAnnotaionView
您可以对 MapAnnotationView 执行类似的模式。
总是一样的:你尝试出队。如果失败,您将创建一个新的。对于每个不同的
if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: ClusterAnnotationView.REUSEIDENTIFIER) as? TimeAnnotationView {
dequeuedView.annotation = clusterAnnotation
return dequeuedView
} else {
let clusterAnnotationView = ClusterAnnotationView(annotation: timeAnnotation, reuseIdentifier: ClusterAnnotationView.REUSEIDENTIFIER)
returnclusterAnnotationView
}
子类,您使用不同的
MKMarkerAnnotaionView
。