如何从转义闭包中获取值并将其分配给变量并显示在表视图中
how to get a value from an escaping closure and assign it to a variable and display in tableview
我使用 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 问题,但我不知道如何修改它以在 table 单元格中成功显示距离。请帮忙
问题在老师的帮助下解决了。
解决方案是创建一个实例变量,然后直接在闭包中调用 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")
}
})
}
我使用 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 问题,但我不知道如何修改它以在 table 单元格中成功显示距离。请帮忙
问题在老师的帮助下解决了。 解决方案是创建一个实例变量,然后直接在闭包中调用 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")
}
})
}