У меня есть пользовательская аннотация для моего mapView.Сначала я установил для него координаты, заголовок (например, «первый заголовок»), subTitle (например, «первый адрес»), userId и расстояние (например, 0 метров) с некоторыми данными.Я добавляю его в mapView и в массив для последующего использования.Все работает, это показывает на mapView, я нажимаю его, и выноска показывает, что исходные данные.
Позже я получаю обновление, что местоположение для этой выноски изменилось.Я перебираю массив и обновляю выноску новыми данными для свойств координат, заголовка (например, «новый заголовок»), подзаголовка (например, «новый адрес») и расстояния (например, 100 метров).Я также анимирую выноску из исходного местоположения в новое местоположение.Анимация работает нормально, и выноска перемещается из точки А в точку Б.
Проблема заключается в том, что, когда я нажимаю аннотацию, старые данные отображаются в выноске вместо новых данных.
Iиспользуйте calloutAccessoryControlTapped
, чтобы нажать на новый vc.Когда я ставлю точку останова, пользовательский пин-код имеет все новые данныеПохоже, что ошибка произошла с выноской.
Как это исправить?
Я не хочу удалять все аннотации из mapView, так что это невариант.Я звоню mapView.removeAnnotation(customPin)
и mapView.addAnnotation(customPin)
, что устраняет проблему для этого пина, но есть мигание, когда пин удален и добавлен обратно на карту, а затем, когда он анимируется в новое местоположение, он выглядит прерывистым.
Пользовательская аннотация
class CustomPin: NSObject, MKAnnotation {
@objc dynamic var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?
var userId: String?
var distance: CLLocationDistance?
init(coordinate: CLLocationCoordinate2D, title: String, subtitle: String, userId: String, distance: CLLocationDistance?) {
self.coordinate = coordinate
self.title = title
self.subtitle = subtitle
self.userId = userId
self.distance = distance
super.init()
}
}
Первый раз, когда аннотация устанавливается с начальными данными
firstFunctionThatGetsTheInitialLocation(origLat, origLon) {
let firstCoordinate = CLLocationCoordinate2DMake(origLat, origLon)
let distanceInMeters: CLLocationDistance = self.center.distance(from: anotherUsersLocation)
let customPin = CustomPin(coordinate: firstCoordinate, title: "first title", subtitle: "first address", userId: "12345", distance: distance)
DispatchQueue.main.async { [weak self] in
self?.mapView.addAnnotation(customPin)
self?.arrOfPins.append(customPin)
}
}
Второй раз, когда аннотация устанавливается с новыми данными
secondFunctionThatGetsTheNewLocation(newCoordinate: CLLocationCoordinate2D, newDistance: CLLocationDistance) {
for pin in customPins {
pin.title = "second title" // ** updates but the callout doesn't reflect it
pin.subTitle = "second address" // ** updates but the callout doesn't reflect it
pin.distance = newDistance // ** updates but the callout doesn't reflect it
// calling these gives me the new data but the annotation blinks and moves really fast to it's new location
// mapView.removeAnnotation(pin)
// mapView.addAnnotation(pin)
UIView.animate(withDuration: 1) {
pin.coordinate = newCoordinate // this updates and animates to the new location with no problem
}
}
}
Представление MapViewаннотация
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation.isKind(of: MKUserLocation.self) { return nil }
guard let annotation = annotation as? CustomPin else { return nil }
let reuseIdentifier = "CustomPin"
var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseIdentifier)
if annotationView == nil {
annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: reuseIdentifier)
annotationView?.canShowCallout = true
annotationView?.calloutOffset = CGPoint(x: -5, y: 5)
annotationView?.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)
annotationView?.image = UIImage(named: "chevronImage")
} else {
annotationView?.annotation = annotation
}
annotationView?.detailCalloutAccessoryView = nil
annotationView?.detailCalloutAccessoryView = createCallOutWithDataFrom(customPin: annotation)
return annotationView
}
Создание UIView для выноски
func createCallOutWithDataFrom(customPin: CustomPin) -> UIView {
let titleText = customPin.title
let subTitleText = customPin.subTitle
let distanceText = subTitle.distance // gets converted to a string
// 1. create a UIView
// 2. create some labels and add the text from the title, subTitle, and distance and add them as subViews to the UIView
// 3. return the UIView
}