Mkmap iOS11群集在最大缩放后没有拆分,如何设置?

时间:2017-10-19 10:00:16

标签: mapkit cluster-computing ios11 marker mkannotation

首先,我的代码完全正常运行。 我已经设置好了mapView.register我的注释标记和集群。

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

所以我搜索了一种能够设置这个“缩放级别”的方法,即使彼此非常接近,也会显示我的两个注释。

以下是我在地图上使用高缩放的群集视图: enter image description here

如果我放大最大值: 好吧,其中一个聚类视图分为两个,但没有显示4个注释 enter image description here

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

2 个答案:

答案 0 :(得分:2)

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

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) {
    // https://stackoverflow.com/a/40616239/883413
    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
}

答案 1 :(得分:2)

就我而言,!每个时间!我没有更新clusteringIdentifier

中的“func mapView(_ mapView:MKMapView,viewFor annotation:MKAnnotation)”

mapView.dequeueReusableAnnotationView(withIdentifier:“identifier”,for:annotation)重用MKAnnotationView时,clusteringIdentifier将为 nil 。 (重置)

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

  

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
   }
}
  

关键点(每次都必须更新“clusteringIdentifier”。)

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

    // TODO: Update the annotationView

  }
}

Sample Project Here