如何修复自定义点注释从重叠中消失?
How to fix custom Point Annotations from disappearing from overlap?
正在尝试显示来自 MapKits 本地搜索的自定义点注释。当注释首次加载到地图上时,所有注释都会显示,但随后重叠的注释会消失。而且它们只会在您放大该区域时重新出现。
许多堆栈解决方案已向用户说明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
}
我想要这样,当用户进行本地搜索时,它会显示所有注释,无论它们是否彼此靠近,而无需放大。
当前地图视图的图像:
您显然没有为您的地图视图设置 delegate
,因为这些注释视图不是 MKPinAnnotationView
,而是默认的 MKMarkerAnnotationView
。如果您要实现 MKMapViewDelegate
方法,则必须设置地图视图的 delegate
(在 IB 中或以编程方式)。
这种消失的行为是因为默认MKMarkerAnnotationView
配置为启用集群,但您还没有注册MKMapViewDefaultClusterAnnotationViewReuseIdentifier
。
因此,如果您真的想要图钉注释视图而不想要集群,请设置您的地图视图 delegate
,您的方法应该可以完成您想要的。
我个人建议您通过将注释视图的配置移动到 MKPinAnnotationView
subclass:
来减少视图控制器的膨胀
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
中,您可以注册 class,而不必实施 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)
然后您就可以毫不费力地享受集群。
正在尝试显示来自 MapKits 本地搜索的自定义点注释。当注释首次加载到地图上时,所有注释都会显示,但随后重叠的注释会消失。而且它们只会在您放大该区域时重新出现。
许多堆栈解决方案已向用户说明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
}
我想要这样,当用户进行本地搜索时,它会显示所有注释,无论它们是否彼此靠近,而无需放大。
当前地图视图的图像:
您显然没有为您的地图视图设置 delegate
,因为这些注释视图不是 MKPinAnnotationView
,而是默认的 MKMarkerAnnotationView
。如果您要实现 MKMapViewDelegate
方法,则必须设置地图视图的 delegate
(在 IB 中或以编程方式)。
这种消失的行为是因为默认MKMarkerAnnotationView
配置为启用集群,但您还没有注册MKMapViewDefaultClusterAnnotationViewReuseIdentifier
。
因此,如果您真的想要图钉注释视图而不想要集群,请设置您的地图视图 delegate
,您的方法应该可以完成您想要的。
我个人建议您通过将注释视图的配置移动到 MKPinAnnotationView
subclass:
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
中,您可以注册 class,而不必实施 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)
然后您就可以毫不费力地享受集群。