TableViewCelll многоразовый идентификатор LocationManager

#swift #uitableview #cllocationmanager

#swift #uitableview #cllocationmanager

Вопрос:

Я пытаюсь отобразить расстояние между двумя координатами в метке внутри tableViewCell, но каждый раз, когда я прокручиваю, данные метки меняются… Я знаю, что мне нужно использовать повторно используемые идентификаторы, но все, что я пробовал, не работает…

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    let cell = tableView.dequeueReusableCell(withIdentifier: "JobCell", for: indexPath) as! JobTableViewCell
    let job = jobs[indexPath.row]
    cell.job = job
    cell.categorie.text = job.categorie
    cell.distance.text = JobTableViewCell.takenLocation
    return cell
}
  

И я вычисляю расстояние внутри класса tableViewCell

 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let lastLocation = locations.last {
        let geocoder = CLGeocoder()
        //get job coordinates
        geocoder.geocodeAddressString(job.location) { placemarks, error in
            let placemarkW = placemarks?.first
            if let placemark = placemarkW
            {
                let lat = placemark.location?.coordinate.latitude
                let lon = placemark.location?.coordinate.longitude
                let jobLocation = CLLocation(latitude: lat!, longitude: lon!)
                //get user coordinates
                let myLocation = CLLocation(latitude: lastLocation.coordinate.latitude, longitude: lastLocation.coordinate.longitude)
                //get distance between coordinates
                let distance = myLocation.distance(from: jobLocation) / 1000
                self.distance.text = String(format: "%.01fkm", distance)
                self.job.distance = distance
                JobTableViewCell.takenLocation = String(format: "%.01km", distance)
            } else {
                self.distance.text = "Not Valid"
                self.job.distance = 0.0
                
            }
            self.reloading?.reloadIt()
        }
    }
    self.location.stopUpdatingLocation()
    guard let _: CLLocationCoordinate2D = manager.location?.coordinate else { return }
}
  

Я слышал, что не использовать ячейки повторно — очень плохая идея, так есть ли какой-нибудь способ решить мою проблему? (Кстати. метка категории работает)

РЕДАКТИРОВАТЬ новый класс для вычисления:

 class CalculateDistance: NSObject, CLLocationManagerDelegate{

var reloading:Reloading?
let location = CLLocationManager()
var job: Job!
var noDistance: String = ""
static var gettingDistance: String = ""

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let lastLocation = locations.last {
        let geocoder = CLGeocoder()
        //get job coordinates
        geocoder.geocodeAddressString(job.location) { placemarks, error in
            let placemarkW = placemarks?.first
            if let placemark = placemarkW
            {
                let lat = placemark.location?.coordinate.latitude
                let lon = placemark.location?.coordinate.longitude
                let jobLocation = CLLocation(latitude: lat!, longitude: lon!)
                //get user coordinates
                let myLocation = CLLocation(latitude: lastLocation.coordinate.latitude, longitude: lastLocation.coordinate.longitude)
                //get distance between coordinates
                let distance = myLocation.distance(from: jobLocation) / 1000
                CalculateDistance.gettingDistance = String(format: "%.01fkm", distance)
            } else {
                self.noDistance = "Not Valid"
            }
            self.reloading?.reloadIt()
        }
    }
    self.location.stopUpdatingLocation()
    guard let _: CLLocationCoordinate2D = manager.location?.coordinate else { return }
}

}
  

Комментарии:

1. Ваша основная проблема заключается в том, что takenLocation для всех ваших ячеек есть только одна общая. При прокрутке cellForRowAt вызывается для разных ячеек, но takenLocation обновляется из асинхронного метода geocodeAddressString . Это означает, что вы не можете быть уверены, какое задание ячейки использовалось в последнем вычислении.

Ответ №1:

  1. Создайте отдельный класс для вычисления местоположения. Задача ячейки — отображать пользовательский интерфейс и взаимодействовать с пользователем.
  2. В вашем коде геокодер предоставит вам метки по завершении, он работает асинхронно, это означает, что ячейка TableView будет загружена, но метки появятся позже. Вычислите расстояние и, как только вы его получите, вызовите TableView.reloadData() (не забудьте вызвать его в основной очереди.

Если вам нужна дополнительная информация, не стесняйтесь спрашивать!