MapKit 注释消失
MapKit Annotations Disappearing
我有一个纬度数组和另一个经度数组,我将它们添加到 CLLocationCoordinate2D 类型的数组中。然后我使用新数组在地图上注释多个点。一些,或者大部分,甚至可能是所有的注释都显示在地图上,但是当我放大(是的,放大)时,一些注释消失了,然后又回来了,或者没有。关于如何让它们全部可见的任何想法?这是我在缩小而不是缩小时期望的行为。
这是我用于上述内容的代码。
import UIKit
import MapKit
import CoreLocation
class MultiMapVC: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var multiEventMap: MKMapView!
var latDouble = Double()
var longDouble = Double()
let manager = CLLocationManager()
var receivedArrayOfLats = [Double]()
var receivedArrayOfLongs = [Double]()
var locations = [CLLocationCoordinate2D]()
func locationManager(_ manager: CLLocationManager, didUpdateLocations uLocation: [CLLocation]) {
let userLocation = uLocation[0]
let span:MKCoordinateSpan = MKCoordinateSpanMake(0.3, 0.3)
let usersLocation = userLocation.coordinate
let region:MKCoordinateRegion = MKCoordinateRegionMake(usersLocation, span)
multiEventMap.setRegion(region, animated: true)
manager.distanceFilter = 1000
self.multiEventMap.showsUserLocation = true
}
func multiPoint() {
var coordinateArray: [CLLocationCoordinate2D] = []
print ("Received Longitude Count = \(receivedArrayOfLongs.count)")
print ("Received Latitude Count = \(receivedArrayOfLats.count)")
if receivedArrayOfLats.count == receivedArrayOfLongs.count {
for i in 0 ..< receivedArrayOfLats.count {
let eventLocation = CLLocationCoordinate2DMake(receivedArrayOfLats[i], receivedArrayOfLongs[i])
coordinateArray.append(eventLocation)
print (coordinateArray.count)
}
}
for events in coordinateArray {
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: events.latitude, longitude: events.longitude)
multiEventMap.addAnnotation(annotation)
}
}
override func viewDidLoad() {
super.viewDidLoad()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
multiPoint()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
multiEventMap.removeFromSuperview()
self.multiEventMap = nil
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
我遇到了类似的问题。我最好的猜测是它与 iOS 11 检测引脚冲突的方式有关。实施自定义注释视图或恢复使用 iOS 10 针为我解决了问题。
例如,实施以下内容应该可以修复您的代码:
class MultiMapVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard let annotation = annotation as? MKPointAnnotation else { return nil }
let identifier = "pin-marker"
var view: MKAnnotationView
if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView {
dequeuedView.annotation = annotation
view = dequeuedView
} else {
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
}
return view
}
}
如果这不起作用,有一个 displayPriority
属性 值得研究,因为它负责帮助确定何时应 hidden/shown 在不同的缩放水平。更多信息请见 https://developer.apple.com/documentation/mapkit/mkannotationview/2867298-displaypriority
希望对您有所帮助。
NiltiakSivad 的解决方案有效,但它恢复到旧的 iOS 10 外观。如果你想为 iOS 11 保留新的 iOS 11 气球标记,并只使用旧的图钉查找旧的 iOS 版本,那么你可以按如下方式实现委托方法:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let reuseIdentifier = "annotationView"
var view = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
if #available(iOS 11.0, *) {
if view == nil {
view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
view?.displayPriority = .required
} else {
if view == nil {
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
}
view?.annotation = annotation
view?.canShowCallout = true
return view
}
我只在第一次分配 MKMarkerAnnotationView 时才设置 annotationView.displayPriority = .required
。通常这就是您需要做的所有事情,但每次重新使用单元格时设置它对我来说解决了这个问题。
Leszek Szary 接受的答案是正确的。
但是有一些细则。有时 MKMarkerAnnotationView
不会呈现,即使
view.displayPriority = .required
已设置。
您看到的是不同规则的组合。
MKAnnotationViews
从地图的上到下呈现。 (不管是北在哪)。
- 如果
MapKit
决定重叠绘制MKAnnotationViews
,那么靠近底部的MKAnnotationView
被绘制在上面(因为它是稍后绘制的)
- 不仅
MKAnnotationViews
,MKMArkerAnnotationViews
下方呈现的标题也需要space。这些标题的呈现受 markerView.titleVisibility
影响。如果 markerView.titleVisibility
设置为 .visible
(而不是默认的 .adaptive
),则此标题比稍后呈现的 MarkerAnnotationView
更强,即使后面的 MarkerAnnotationView
有一个 displayPriority = .required
。靠近底部的 MarkerAnnotationView
未渲染。
- 如果靠近顶部的
MarkerAnnotationView
有一个较低的 displayPriority
,甚至会发生这种情况。因此 displayPriority
和 .titleVisibility = .visible
的 MarkerAnnotationView
可以使 MarkerAnnotationView
更接近底部 displayPriority = .required
消失。
我不知道有关此行为的文档。这是我用 iOS 12 实验的结果。我的描述是简化的。
我在 Xcode 10 和 iOS 12+ 作为我的部署目标时看到了类似的问题。来自 Apple 员工 (https://forums.developer.apple.com/thread/92839) 的 post 建议在出队标记上切换 .isHidden
属性。这已经改善了一些事情,但并没有完全解决问题。
result?.isHidden = true
result?.isHidden = false
return result
我有一个纬度数组和另一个经度数组,我将它们添加到 CLLocationCoordinate2D 类型的数组中。然后我使用新数组在地图上注释多个点。一些,或者大部分,甚至可能是所有的注释都显示在地图上,但是当我放大(是的,放大)时,一些注释消失了,然后又回来了,或者没有。关于如何让它们全部可见的任何想法?这是我在缩小而不是缩小时期望的行为。
这是我用于上述内容的代码。
import UIKit
import MapKit
import CoreLocation
class MultiMapVC: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var multiEventMap: MKMapView!
var latDouble = Double()
var longDouble = Double()
let manager = CLLocationManager()
var receivedArrayOfLats = [Double]()
var receivedArrayOfLongs = [Double]()
var locations = [CLLocationCoordinate2D]()
func locationManager(_ manager: CLLocationManager, didUpdateLocations uLocation: [CLLocation]) {
let userLocation = uLocation[0]
let span:MKCoordinateSpan = MKCoordinateSpanMake(0.3, 0.3)
let usersLocation = userLocation.coordinate
let region:MKCoordinateRegion = MKCoordinateRegionMake(usersLocation, span)
multiEventMap.setRegion(region, animated: true)
manager.distanceFilter = 1000
self.multiEventMap.showsUserLocation = true
}
func multiPoint() {
var coordinateArray: [CLLocationCoordinate2D] = []
print ("Received Longitude Count = \(receivedArrayOfLongs.count)")
print ("Received Latitude Count = \(receivedArrayOfLats.count)")
if receivedArrayOfLats.count == receivedArrayOfLongs.count {
for i in 0 ..< receivedArrayOfLats.count {
let eventLocation = CLLocationCoordinate2DMake(receivedArrayOfLats[i], receivedArrayOfLongs[i])
coordinateArray.append(eventLocation)
print (coordinateArray.count)
}
}
for events in coordinateArray {
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: events.latitude, longitude: events.longitude)
multiEventMap.addAnnotation(annotation)
}
}
override func viewDidLoad() {
super.viewDidLoad()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
multiPoint()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
multiEventMap.removeFromSuperview()
self.multiEventMap = nil
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
我遇到了类似的问题。我最好的猜测是它与 iOS 11 检测引脚冲突的方式有关。实施自定义注释视图或恢复使用 iOS 10 针为我解决了问题。
例如,实施以下内容应该可以修复您的代码:
class MultiMapVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard let annotation = annotation as? MKPointAnnotation else { return nil }
let identifier = "pin-marker"
var view: MKAnnotationView
if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView {
dequeuedView.annotation = annotation
view = dequeuedView
} else {
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
}
return view
}
}
如果这不起作用,有一个 displayPriority
属性 值得研究,因为它负责帮助确定何时应 hidden/shown 在不同的缩放水平。更多信息请见 https://developer.apple.com/documentation/mapkit/mkannotationview/2867298-displaypriority
希望对您有所帮助。
NiltiakSivad 的解决方案有效,但它恢复到旧的 iOS 10 外观。如果你想为 iOS 11 保留新的 iOS 11 气球标记,并只使用旧的图钉查找旧的 iOS 版本,那么你可以按如下方式实现委托方法:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let reuseIdentifier = "annotationView"
var view = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
if #available(iOS 11.0, *) {
if view == nil {
view = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
view?.displayPriority = .required
} else {
if view == nil {
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
}
}
view?.annotation = annotation
view?.canShowCallout = true
return view
}
我只在第一次分配 MKMarkerAnnotationView 时才设置 annotationView.displayPriority = .required
。通常这就是您需要做的所有事情,但每次重新使用单元格时设置它对我来说解决了这个问题。
Leszek Szary 接受的答案是正确的。
但是有一些细则。有时 MKMarkerAnnotationView
不会呈现,即使
view.displayPriority = .required
已设置。
您看到的是不同规则的组合。
MKAnnotationViews
从地图的上到下呈现。 (不管是北在哪)。- 如果
MapKit
决定重叠绘制MKAnnotationViews
,那么靠近底部的MKAnnotationView
被绘制在上面(因为它是稍后绘制的) - 不仅
MKAnnotationViews
,MKMArkerAnnotationViews
下方呈现的标题也需要space。这些标题的呈现受markerView.titleVisibility
影响。如果markerView.titleVisibility
设置为.visible
(而不是默认的.adaptive
),则此标题比稍后呈现的MarkerAnnotationView
更强,即使后面的MarkerAnnotationView
有一个displayPriority = .required
。靠近底部的MarkerAnnotationView
未渲染。 - 如果靠近顶部的
MarkerAnnotationView
有一个较低的displayPriority
,甚至会发生这种情况。因此displayPriority
和.titleVisibility = .visible
的MarkerAnnotationView
可以使MarkerAnnotationView
更接近底部displayPriority = .required
消失。
我不知道有关此行为的文档。这是我用 iOS 12 实验的结果。我的描述是简化的。
我在 Xcode 10 和 iOS 12+ 作为我的部署目标时看到了类似的问题。来自 Apple 员工 (https://forums.developer.apple.com/thread/92839) 的 post 建议在出队标记上切换 .isHidden
属性。这已经改善了一些事情,但并没有完全解决问题。
result?.isHidden = true
result?.isHidden = false
return result