【问题标题】:How to fix custom Point Annotations from disappearing from overlap?如何修复自定义点注释从重叠中消失?
【发布时间】:2019-04-23 21:31:37
【问题描述】:

尝试显示来自 MapKit 本地搜索的自定义点注释。当注释第一次加载到地图上时,所有注释都会显示,但随后重叠的注释就会消失。只有当您放大该区域时,它们才会重新出现。

许多堆栈解决方案已向用户view?.displayPriority = .required 说明。但是由于某种原因,这行代码不起作用。

按下按钮时的本地搜索功能

@IBAction func groceryLocalSearch(_ sender: Any) {
    self.localStoresArray.removeAll()
    self.LocalMapKit.removeAnnotations(self.LocalMapKit.annotations)
    currentLocationBtn.isHidden = false
    localRequest.naturalLanguageQuery = "Grocery"
    //localRequest.region = LocalMapKit.region

    self.localSearchBtn.isEnabled = false

    let search = MKLocalSearch(request: localRequest)

    search.start(completionHandler: {(response, error) in

        if error != nil{
            print("Error occured when searching: \(error!.localizedDescription)")
        } else if response!.mapItems.count == 0 {
            print("There were no results in the search")
        } else {
            print("\(response!.mapItems.count) Results found!")
            for item in response!.mapItems {
                //Add each item to a array to access in table view
                self.localStoresArray.append(item)
                let stores = MKPointAnnotation()
                stores.title = item.name
                stores.coordinate = item.placemark.coordinate
                self.LocalMapKit.addAnnotation(stores)
            }
        }
        self.LocalMapKit.showAnnotations(self.LocalMapKit.annotations, animated: true)
        self.localStoresTableView.reloadData()
    })

查看注释功能

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?{
    guard annotation is MKPointAnnotation else { return nil }

    let identifier = "Annotation"

    var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier)

    if annotationView == nil {
        annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
        annotationView?.displayPriority = .required
        //annotationView?.canShowCallout = true
    } else {
        annotationView!.annotation = annotation

    }

    return annotationView
}

我希望这样当用户进行本地搜索时,它会显示所有注释,无论它们是否彼此靠近,而无需放大。

当前地图视图的图像:

【问题讨论】:

    标签: ios swift mapkitannotation


    【解决方案1】:

    您显然没有为地图视图设置delegate,因为这些注释视图不是MKPinAnnotationView,而是默认的MKMarkerAnnotationView。如果要实现MKMapViewDelegate 方法,则必须设置地图视图的delegate(在 IB 中或以编程方式)。

    这种消失的行为是因为默认MKMarkerAnnotationView 配置为启用集群,但您尚未注册MKMapViewDefaultClusterAnnotationViewReuseIdentifier

    所以,如果你真的想要 pin annotation 视图并且你不想要集群,设置你的 map view 的 delegate 并且你的方法应该完成你想要的。


    我个人建议您通过将注释视图的配置移动到 MKPinAnnotationView 子类中来减少视图控制器膨胀:

    class CustomAnnotationView: MKPinAnnotationView { // or use `MKMarkerAnnotationView` if you want
        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")
        }
    }
    

    然后,如果您的目标是 iOS 11 及更高版本,则可以在您的 viewDidLoad 中注册您的课程,而您根本不必实现 mapView(_:viewFor:)

    mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
    

    或者,如果你想正确地享受集群,你可以扩展你的CustomAnnotationView

    class CustomAnnotationView: MKPinAnnotationView { // or use `MKMarkerAnnotationView` if you want
        static let preferredClusteringIdentifier: String? = Bundle.main.bundleIdentifier! + ".CustomAnnotationView"
    
        override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
            super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
            clusteringIdentifier = CustomAnnotationView.preferredClusteringIdentifier
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
        override var annotation: MKAnnotation? {
            didSet {
                clusteringIdentifier = CustomAnnotationView.preferredClusteringIdentifier
            }
        }
    }
    

    然后注册你的注解视图和集群注解视图:

    mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
    mapView.register(MKMarkerAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier)
    

    然后您就可以轻松地进行集群了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-08
      • 2014-08-11
      • 1970-01-01
      • 2023-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多