【问题标题】:How to stop an MKClusterAnnotation from displaying a callout如何阻止 MKClusterAnnotation 显示标注
【发布时间】:2021-02-22 21:28:05
【问题描述】:

问题:如何防止 MKClusterAnnotation 显示标注?

背景:我是编程初学者,请温柔。我正在尝试制作一个基于 MapKit 的应用程序,该应用程序在地图上显示多个站点。我用 GeoJSON 中的虚拟位置填充了地图,效果很好。然而,虽然标注对单个注释有意义,但我宁愿不要让它们出现在集群注释中。我无法弄清楚如何从集群中删除标注。

我的注释是这样创建的:

    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        
       if annotation is MKUserLocation {
       return nil
        } else {
            
            let identifier = "site"
            var marker: MKMarkerAnnotationView
            
            if let dequeuedView = mapView.dequeueReusableAnnotationView(
                withIdentifier: identifier) as? MKMarkerAnnotationView {
                dequeuedView.annotation = annotation
                marker = dequeuedView
                                
            } else {
                marker = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            }
            
            marker.canShowCallout = true // How can I turn this false if callout is a cluster?
            marker.markerTintColor = .systemBlue
            marker.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
            marker.glyphImage = UIImage(systemName: "star")
            marker.clusteringIdentifier = "clusteringIdentifier"
            
            return marker
            
        }
    }

这是我的 MKClusterAnnotation:


    func mapView(_ mapView: MKMapView, clusterAnnotationForMemberAnnotations memberAnnotations: [MKAnnotation]) -> MKClusterAnnotation {

        let cluster = MKClusterAnnotation(memberAnnotations: memberAnnotations)
        cluster.title = "More things to see here"
        cluster.subtitle = "Zoom further in"
        return cluster
        
    }

这可能非常简单,但我无法自己找到它(或通过查看 Apple 文档)。任何帮助表示赞赏! (另外,如果您在我的代码中看到任何愚蠢的东西,请不要害怕指出)。

【问题讨论】:

    标签: swift mapkit mkannotation mkclusterannotation


    【解决方案1】:

    首先,我们不再需要编写viewFor 或方法(除非您需要自定义逻辑来实现多个注解和集群注解)。如今,我们让操作系统为我们做这件事。我们只是将这些配置移动到它们自己的对象中,并将它们注册到地图视图中。

    所以,在viewDidLoad

    mapView.register(MyAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
    mapView.register(MyClusterAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier)
    

    并定义前者使用标注:

    //  MyAnnotationView.swift
    
    import MapKit
    
    class MyAnnotationView: MKMarkerAnnotationView {
        override var annotation: MKAnnotation? { didSet { update(for: annotation) } }
    
        override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
            super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
    
            configure(for: annotation)
        }
    
        required init?(coder: NSCoder) {
            super.init(coder: coder)
    
            configure()
        }
    }
    
    private extension MyAnnotationView {
        func configure(for annotation: MKAnnotation? = nil) {
            canShowCallout = true
            markerTintColor = .systemBlue
            rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
            glyphImage = UIImage(systemName: "star")
    
            update(for: annotation)
        }
    
        func update(for annotation: MKAnnotation?) {
            clusteringIdentifier = "clusteringIdentifier"
            displayPriority = .required
        }
    }
    

    而后者不使用标注:

    //  MyClusterAnnotationView.swift
    
    import MapKit
    
    class MyClusterAnnotationView: MKMarkerAnnotationView {
        override var annotation: MKAnnotation? { didSet { update(for: annotation) } }
    
        override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
            super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
    
            update(for: annotation)
        }
    
        required init?(coder: NSCoder) {
            super.init(coder: coder)
    
            update()
        }
    }
    
    private extension MyClusterAnnotationView {
        func update(for annotation: MKAnnotation? = nil) {
            markerTintColor = .systemGray
        }
    }
    

    MyAnnotationViewMyClusterAnnotationView 的类名可能应该替换为更有意义的名称,但合适的名称可能取决于注解视图的功能用途。

    【讨论】:

    • 太好了,非常感谢。我猜我的教材不是最新的,我没有意识到这一点。
    • 哦,但是我应该将自定义集群 titlesubtitle 放回哪里?
    • 对不起,我说错了。您可以在MKMapViewDelegate 中使用您的clusterAnnotationForMemberAnnotations。我已经修改了上面的答案。
    猜你喜欢
    • 1970-01-01
    • 2014-06-26
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    相关资源
    最近更新 更多