#ios #swift #mapkit #mapkitannotation
#iOS #swift #mapkit #mapkitannotation
Вопрос:
У меня есть массив широт и другой массив долгот, которые я добавляю в массив типа 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.
}
}
Комментарии:
1. Пожалуйста, поделитесь своим кодом метода аннотации viewFor
2. Я сталкиваюсь с той же проблемой, похоже, она присутствует только в iOS 11.
3. Я обновился, чтобы включить весь код из моего VC .. Однако у меня нет метода viewForAnnotation.
4. Это все еще происходит на iOS 13.
Ответ №1:
Решение NiltiakSivad работает, но оно возвращается к старому виду iOS 10. Если вы хотите сохранить новые маркеры воздушных шаров iOS 11 для iOS 11 и использовать старый pin-код, ищите только более старые версии 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
}
Комментарии:
1. На самом деле, вероятно, это ошибка Apple, поскольку приоритет отображения по умолчанию должен быть
.required
(но, по-видимому, это не так!)2. (Кстати, вы не должны ссылаться на другой ответ как «выше» или «ниже», поскольку их порядок меняется в зависимости от их оценок. Вместо этого вы должны написать «решение NiltiakSivad». Я соответствующим образом отредактирую ваш ответ.)
Ответ №2:
Принятый ответ от Лешека Сары правильный.
Но есть некоторые нюансы. Иногда MKMarkerAnnotationView
s не отображаются, даже если
view.displayPriority = .required
установлено.
То, что вы видите, представляет собой комбинацию разных правил.
MKAnnotationViews
отображаются сверху вниз карты. (Не имеет значения, где находится север).- Если
MapKit
вы решите нарисовать перекрытиеMKAnnotationViews
, тоMKAnnotationView
более близкое к низу будет нарисовано сверху (потому что оно будет нарисовано позже) - Мало того
MKAnnotationViews
, что заголовки, отображаемые нижеMKMArkerAnnotationViews
, нуждаются в пространстве. На отображение этих заголовков влияетmarkerView.titleVisibility
. ЕслиmarkerView.titleVisibility
установлено значение.visible
(вместо значения по умолчанию.adaptive
), то этот заголовок сильнее, чем aMarkerAnnotationView
, который отображается позже, даже если у более позднегоMarkerAnnotationView
есть adisplayPriority = .required
.MarkerAnnotationView
Ближе к нижней части не отображается. - Это происходит даже в том случае, если
MarkerAnnotationView
ближе к вершине имеет низкийdisplayPriority
уровень. Таким образом, aMarkerAnnotationView
с низкимdisplayPriority
и.titleVisibility = .visible
можетMarkerAnnotationView
приблизиться к низу сdisplayPriority = .required
исчезновением.
Я не знаю документации об этом поведении. Это результат моих экспериментов с iOS 12. Мое описание sipmplified.
Ответ №3:
Я столкнулся с аналогичной проблемой. Я предполагаю, что это как-то связано с тем, как iOS 11 обнаруживает столкновения контактов. Реализация пользовательского представления аннотаций или возврат к использованию pin-кода 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
свойство, на которое стоит обратить внимание, поскольку оно отвечает за то, чтобы помочь определить, когда контакты должны быть скрыты / показаны на разных уровнях масштабирования. Больше информации на https://developer.apple.com/documentation/mapkit/mkannotationview/2867298-displaypriority
Надеюсь, это поможет.
Комментарии:
1. Это работает! Одна вещь, которую я заметил, это то, что эти выводы нельзя выбрать.
Ответ №4:
Я устанавливал annotationView.displayPriority = .required
только тогда, когда MKMarkAnnotationView был впервые выделен. Обычно это все, что вам нужно сделать, но установка этого параметра каждый раз при повторном использовании ячейки устранила проблему для меня.
Ответ №5:
Я видел аналогичную проблему с Xcode 10 и iOS 12 в качестве моей цели развертывания. Сообщение от сотрудника Apple (https://forums.developer.apple.com/thread/92839 ) рекомендует переключить .isHidden
свойство на удаленном из очереди маркере. Это улучшило ситуацию, но не полностью решило проблему.
result?.isHidden = true
result?.isHidden = false
return result