我正在对注释进行聚类。
下面的代码可以正常工作,并且可以在iOS 11和iOS 12中正确聚集点。
这无法聚集点,从而降低了iOS 13中的点。
我没有使用任何beta版本。
TTMapView类是MKMapView的包装器。
class TTMapView: UIView {
var mapView = MKMapView()
private var mapObjects: Dictionary<TTShape, MKShape?> = [:]
private var _isClusteringEnabled = true
func addMarker(_ marker: TTPoint) -> TTPoint {
removeMarker(marker)
let coordinate = marker.coordinate
let pointAnnotation = MKPointAnnotation()
pointAnnotation.coordinate = convertTTCoordinateToCLLocationCoordinate2D(coordinate)
pointAnnotation.title = marker.title
pointAnnotation.subtitle = marker.subtitle
mapObjects.updateValue(pointAnnotation, forKey: marker)
mapView.addAnnotation(pointAnnotation)
return marker
}
}
extension TTMapView: MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
if _isClusteringEnabled {
let point = mapObjects.filter ({ $0.value === annotation }).first?.key as? TTPoint
print("point ", point)
return TTClusterAnnotationView(annotation: annotation, reuseIdentifier: TTClusterAnnotationView.ReuseID, image: point?.image, color: point?.tintColor)
} else {
let reuseId = "simplePin"
var pinAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId)
if pinAnnotationView == nil {
pinAnnotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinAnnotationView?.isDraggable = true
pinAnnotationView?.canShowCallout = true
}
return pinAnnotationView
}
}
}
class TTClusterAnnotationView: MKMarkerAnnotationView {
/// Use this Id for setting annotation
static let ReuseID = "clusterAnnotation"
init(annotation: MKAnnotation?, reuseIdentifier: String?, image: UIImage?, color: UIColor? = nil) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
// Enable clustering by just setting the clusteringIdentifier
clusteringIdentifier = "clusteringIdentifier"
glyphImage = image
glyphTintColor = color
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func prepareForDisplay() {
super.prepareForDisplay()
displayPriority = .required
}
}
答案 0 :(得分:0)
进行集群注释视图(这是集群的注释视图,不要与具有clusteringIdentifier
的现有注释视图混淆,我将其重命名为CustomAnnotationView
以避免混淆)的displayPriority
中的.required
:
class CustomClusterAnnotationView: MKMarkerAnnotationView {
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
displayPriority = .required
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var annotation: MKAnnotation? {
didSet {
displayPriority = .required
}
}
}
然后注册该课程:
mapView.register(CustomClusterAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier)
然后使用它:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
if annotation is MKClusterAnnotation {
return nil
}
...
}
一些无关的发现:
我建议您仅将图像和颜色属性添加到自定义注释类型中,而不要使用viewFor
到mapObjects
进行过滤。所以:
class CustomAnnotation: MKPointAnnotation {
let image: UIImage
let color: UIColor
init(coordinate: CLLocationCoordinate2D, title: String?, image: UIImage, color: UIColor) {
self.image = image
self.color = color
super.init()
self.coordinate = coordinate
self.title = title
}
}
然后,如果您使用的不是MKPointAnnotation
,则自定义注释视图可以将颜色和图像信息直接从注释中拉出。
class CustomAnnotationView: MKMarkerAnnotationView {
static let reuseID = "CustomAnnotationView"
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
updateForAnnotation()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var annotation: MKAnnotation? {
didSet {
updateForAnnotation()
}
}
}
private extension CustomAnnotationView {
func updateForAnnotation() {
clusteringIdentifier = "CustomAnnotationView"
displayPriority = .required
if let annotation = annotation as? CustomAnnotation {
glyphImage = annotation.image
glyphTintColor = annotation.color
} else {
glyphImage = nil
glyphTintColor = nil
}
}
}
请注意,在上方,我要重置didSet
的{{1}}中的群集标识符,图像,字形等。这样可以重用注释视图。 (请参阅下一点。)
引脚注释视图的重用逻辑不正确。如果启用了群集,则根本不会进行重用。如果定位到iOS 11及更高版本,我将使用annotation
来为您解决所有这些问题。因此,我可以注册此重用ID:
dequeueReusableAnnotationView(withIdentifier:for:)
如果要关闭群集,我将对显示的“简单图钉”注释视图重复该过程。
mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: CustomAnnotationView.reuseID)
和
mapView.register(CustomSimplePinAnnotationView.self, forAnnotationViewWithReuseIdentifier: CustomSimplePinAnnotationView.reuseID)
然后简化您的class CustomSimplePinAnnotationView: MKPinAnnotationView {
static let reuseID = "CustomSimplePinAnnotationView"
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
isDraggable = true
canShowCallout = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
:
viewFor