如何阻止 MKClusterAnnotation 显示标注
How to stop an MKClusterAnnotation from displaying a callout
问题:如何防止 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 文档)。任何帮助表示赞赏! (此外,如果您在我的代码中看到任何愚蠢的地方,请不要害怕指出)。
首先,我们不再需要编写 viewFor
或方法(除非您需要为多个注解和集群注解自定义逻辑)。现在,我们让 OS 为我们做这件事。我们只是将它们的配置移动到它们自己的对象中,并将它们注册到 mapview 中。
因此,在 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
}
}
MyAnnotationView
和 MyClusterAnnotationView
的 class 名称可能应该替换为更有意义的名称,但适当的名称可能取决于注释视图的功能目的。
问题:如何防止 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 文档)。任何帮助表示赞赏! (此外,如果您在我的代码中看到任何愚蠢的地方,请不要害怕指出)。
首先,我们不再需要编写 viewFor
或方法(除非您需要为多个注解和集群注解自定义逻辑)。现在,我们让 OS 为我们做这件事。我们只是将它们的配置移动到它们自己的对象中,并将它们注册到 mapview 中。
因此,在 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
}
}
MyAnnotationView
和 MyClusterAnnotationView
的 class 名称可能应该替换为更有意义的名称,但适当的名称可能取决于注释视图的功能目的。