#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:
- Создайте отдельный класс для вычисления местоположения. Задача ячейки — отображать пользовательский интерфейс и взаимодействовать с пользователем.
- В вашем коде геокодер предоставит вам метки по завершении, он работает асинхронно, это означает, что ячейка TableView будет загружена, но метки появятся позже. Вычислите расстояние и, как только вы его получите, вызовите TableView.reloadData() (не забудьте вызвать его в основной очереди.
Если вам нужна дополнительная информация, не стесняйтесь спрашивать!