mkmap iOS11 最大缩放后簇不分裂,如何设置?

Mkmap iOS11 clusters doesn't split up after max zoom, how to set it up?

首先,我的代码是完美的运行。 我已经很好地设置了 mapView.register 我的注释标记和集群。

当我在集群视图中按预期缩小注释融合时, 当我放大时,同样的好结果,除了在某个点。当太多的注释彼此距离太近时,集群视图不再拆分为我的两个注释视图。

所以我寻找一种方法来设置这个 "zoom level" ,即使它们彼此非常接近,也会让我的两个注释出现。

这是我在地图上的高缩放集群视图:

这里如果我放大到最大: 好吧,其中一个集群视图分成了两个,但没有显示 4 个注释。

我也尝试将我的两个注释的 displayPriority 设置为比集群视图更高,但结果仍然相同。 有什么想法吗?

您将需要跟踪地图的缩放级别,并在超过您指定的缩放级别时重新加载注释。

private let maxZoomLevel = 9
private var previousZoomLevel: Int?
private var currentZoomLevel: Int?  {
    willSet {
        self.previousZoomLevel = self.currentZoomLevel
    }
    didSet {
        // if we have crossed the max zoom level, request a refresh
        // so that all annotations are redrawn with clustering enabled/disabled
        guard let currentZoomLevel = self.currentZoomLevel else { return }
        guard let previousZoomLevel = self.previousZoomLevel else { return }
        var refreshRequired = false
        if currentZoomLevel > self.maxZoomLevel && previousZoomLevel <= self.maxZoomLevel {
            refreshRequired = true
        }
        if currentZoomLevel <= self.maxZoomLevel && previousZoomLevel > self.maxZoomLevel {
            refreshRequired = true
        }
        if refreshRequired {
            // remove the annotations and re-add them, eg
            let annotations = self.mapView.annotations
            self.mapView.removeAnnotations(annotations)
            self.mapView.addAnnotations(annotations)
        }
    }
}

private var shouldCluster: Bool {
    if let zoomLevel = self.currentZoomLevel, zoomLevel <= maxZoomLevel {
        return false
    }
    return true
}

func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    // 
    let zoomWidth = mapView.visibleMapRect.size.width
    let zoomLevel = Int(log2(zoomWidth))
    self.currentZoomLevel = zoomLevel
}

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    // for me, annotation reuse doesn't work with clustering
    let annotationView = CustomAnnotationView(annotation: annotation)
    if self.shouldCluster {
        annotationView.clusteringIdentifier = "custom-id"
    } else {
        annotationView.clusteringIdentifier = nil
    }
    return annotationView
}

就我而言,!每次! 我没有更新 clusteringIdentifier

在"func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation)"

当 MKAnnotationView 被 mapView.dequeueReusableAnnotationView(withIdentifier: "identifier", for: annotation) 重用时,clusteringIdentifier 将是 。 (重置)

这就是群集不起作用的原因。

AnnotationView.swift

import MapKit

// MARK: - Define
struct AnnotationViewInfo {
    static let identifier = "AnnotationView"
}


final class AnnotationView: MKAnnotationView {

// MARK: - Initializer
override init(annotation: MKAnnotation!, reuseIdentifier: String!) {
    super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
    setView()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setView()
}

// MARK: - Value
// MARK: Public
override var annotation: MKAnnotation? {
    willSet { update(annotation: newValue) }
}



// MARK: - Function
// MARK: Private
private func setView() {
    if #available(iOS 11.0, *) {
        collisionMode        = .rectangle
        clusteringIdentifier = AnnotationViewInfo.identifier
    }

    canShowCallout = true
    image = #imageLiteral(resourceName: "pin01").resizedImage(size: CGSize(width: #imageLiteral(resourceName: "pin01").size.width/4.0, height: #imageLiteral(resourceName: "pin01").size.height/4.0), scale: 1.0)
}


private func update(annotation: MKAnnotation?) {
    if #available(iOS 11.0, *) {
        clusteringIdentifier = AnnotationViewInfo.identifier
    }

    // TODO: Update the annotationView

  }
}

MKMapViewDelegate

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if #available(iOS 11.0, *) {
    switch annotation {
    case is PointAnnotation:         return mapView.dequeueReusableAnnotationView(withIdentifier: AnnotationView1Info.identifier,       for: annotation)
    case is MKClusterAnnotation:     return mapView.dequeueReusableAnnotationView(withIdentifier: ClusterAnnotationViewInfo.identifier, for: annotation)
    case is MKUserLocation:          return nil
    default:                         return nil
    }

   } else {
      return nil
   }
}

Key Point (You must update the "clusteringIdentifier" every time.)

 private func update(annotation: MKAnnotation?) {
    if #available(iOS 11.0, *) {
        clusteringIdentifier = AnnotationViewInfo.identifier
    }

    // TODO: Update the annotationView

  }
}

Sample Project Here