как получить значение из экранирующего замыкания и присвоить его переменной и отобразить в виде таблицы - PullRequest
0 голосов
/ 02 ноября 2019

Я рассчитал расстояние с помощью CoreLocation, но я не смог назначить расстояние переменной и отобразить значение в Tableview.

Я использовал функцию forwardGeocoding для преобразования String в тип CLLocation и получил расстояние между двумяпятна. И я могу напечатать данные внутри замыкания, но я никогда не смогу назначить расстояние для переменной вне замыкания.

// This function will accept a string and convert to CLLocation
func forwardGeocoding(address:String, completion: @escaping ((CLLocation?) -> Void))
{
    let geocoder = CLGeocoder()
    geocoder.geocodeAddressString(address, completionHandler: { (placemarks, error) in
        if let error = error
        {
            print(error)
            completion(nil)
        }
        else
        {
            // found locations, then perform the next task using closure
            let placemark = placemarks?[0]
            completion(placemark?.location) // execute closure
        }
    })
}

// This function will find the distance, assign it to a local variable and return it 
func searchDistance(_ address: String) -> Double
{
    var distance: Double = 0
    self.forwardGeocoding(address:address, completion: {(location) in
        if let locationTo = location {
            // calculate distance
            distance = (self.mainDelegate.currLocation?.distance(from: locationTo))!
            // distance has value here
            print("distance in closure \(distance)")

        } else {
            // not found destination, show alert
            print("cannot find address")
        }
    })
    print(distance) // fails to catch the distance, always 0
    return distance      
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let tableCell = tableView.dequeueReusableCell(withIdentifier: "DonorCell", for: indexPath) as? DonorListTableViewCell ?? DonorListTableViewCell(style: .default, reuseIdentifier: "DonorCell")

    let index = indexPath.row
    tableCell.donorName?.text = donors[index].organizationName
    tableCell.donorAddress?.text = "\(donors[index].street ?? ""), \( donors[index].city ?? "")"
    tableCell.donorPhone?.text = donors[index].phoneNumber

    let donorAddress = "\(donors[index].street ?? "") \(donors[index].city ?? "") \(donors[index].postalCode ?? "")"

    // This is always 0
    let distanceOnMap = searchDistance(donorAddress)

    return tableCell
}

Я предполагаю, что это проблема @escaping, но я не знаю, как ее изменить, чтобы успешно отобразить расстояние в ячейке таблицы. Пожалуйста, помогите

1 Ответ

0 голосов
/ 05 ноября 2019

Проблема была решена с помощью моего учителя. Решением является создание переменной экземпляра с последующим вызовом self.tableview.reload непосредственно в замыкании. В tableView cellForRowAT, просто загружая значение из переменной экземпляра.

func searchAddress(_ address: String)
{
    self.forwardGeocoding(address:address, completion: {(location) in
        if let locationTo = location {
            // calculate distance
            self.donorDistance.append((self.mainDelegate.currLocation?.distance(from: locationTo) ?? 0))
            print(self.mainDelegate.currLocation?.distance(from: locationTo) ?? 0)
            if self.donorDistance.count == self.donors.count
            {
                self.tableview.reloadData()
            }              
        } else {
            // not found destination, show alert
            print("cannot find address")
        }
    })
}
...