如何从转义闭包中获取值并将其分配给变量并在表格视图中显示

Posted

技术标签:

【中文标题】如何从转义闭包中获取值并将其分配给变量并在表格视图中显示【英文标题】:how to get a value from an escaping closure and assign it to a variable and display in tableview 【发布时间】:2019-11-02 01:35:08 【问题描述】:

我使用 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 问题,但我不知道如何修改它以成功显示表格单元格中的距离。请帮忙

【问题讨论】:

您的代码永远无法运行。 forwardGeocoding异步进行地理编码。 searchDistance 在其完成处理程序中异步取回一个值。在您返回cellForRowAt 中的表格视图的单元格很久之后,所有这些都会发生。 谢谢。那么你知道如何修改以在tableview上显示距离吗? 是的,您的完成处理程序会修改数据模型并重新加载表视图。这就像通过网络获取图像以在表格视图的单元格中使用一样。这个话题已经在这里得到了彻底的解释。 【参考方案1】:

在老师的帮助下问题解决了。 解决方案是创建一个实例变量,然后在闭包中直接调用 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")
        
    )

【讨论】:

以上是关于如何从转义闭包中获取值并将其分配给变量并在表格视图中显示的主要内容,如果未能解决你的问题,请参考以下文章

如何从文本框中获取值并将其分配给 Xcode 中的整数变量?

如何从数组中获取值并在zend框架工作中分配给视图

如何从文本字段中获取值并将其传递给变量?

从对象获取属性值并将其分配给javascript中的变量

从表格视图单元格内的文本字段中获取文本

将值从数据库传递到 vue 组件并将其分配给变量