在模型的类Location
中,我获取当前城市的名称:
var currentLatitude: Double!
var currentLongitude: Double!
var currentLocation: String!
var currentCity: String!
func getLocationName() {
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: currentLatitude, longitude: currentLongitude)
geoCoder.reverseGeocodeLocation(location, completionHandler: { placemarks, error in
guard let addressDict = placemarks?[0].addressDictionary else {
return
}
if let city = addressDict["City"] as? String {
self.currentCity = city
print(city)
}
if let zip = addressDict["ZIP"] as? String {
print(zip)
}
if let country = addressDict["Country"] as? String {
print(country)
}
self.nowUpdateUI()
})
}
在 View Controller 中,我想更新 UI 并更新标签以显示当前城市。 然而, self.currentCity = city 发生在闭包内部。因此,如果我只是在 View Controller 中运行一个函数:
func updateUI() {
cityLbl.text = Location.sharedInstance.currentCity
}
- 我一无所获,因为闭包尚未完成运行。
建议我向
getLocationName()
添加一个完成处理程序,并在其中执行对将更新 UI 的 func 的调用。 然而,从所有关于闭包、完成处理程序的教程中,我不清楚如何实现这一点。 如何构造完成处理程序,将其作为参数传递给getLocationName()
以及如何从 View Controller 调用getLocationName
?
最佳答案
要处理这种情况,您有多种选择。
使用您的位置类创建
委托(delegate)/协议(protocol)
- 创建一个协议(protocol)并使用您的
ViewController
实现该协议(protocol)方法,并在您的Location
类中声明其实例。然后在reverseGeocodeLocation
的completionHandler
中调用这个委托(delegate)方法。查看 Apple 文档Protocol
了解更多详情。
- 创建一个协议(protocol)并使用您的
您可以使用
Location
类的getLocationName
方法创建completionHandler
。使用
getLocationName
添加completionHandler
并在reverseGeocodeLocation 的
像这样。completionHandler
内调用该completionHandler
func getLocationName(completionHandler: @escaping (_ success: Bool) -> Void) { let geoCoder = CLGeocoder() let location = CLLocation(latitude: currentLatitude, longitude: currentLongitude) geoCoder.reverseGeocodeLocation(location, completionHandler: { placemarks, error in guard let addressDict = placemarks?[0].addressDictionary else { completionHandler(false) return } if let city = addressDict["City"] as? String { self.currentCity = city print(city) } if let zip = addressDict["ZIP"] as? String { print(zip) } if let country = addressDict["Country"] as? String { print(country) } completionHandler(true) //self.nowUpdateUI() }) }
现在,在调用此函数的
ViewController
中,调用完成 block 内的updateUI
方法。Location.sharedInstance.getLocationName { (success) in if success {//If successfully got response self.updateUI() } }
您可以为
(NS)NotificationCenter
添加观察者。- 使用
(NS)NotificationCenter
注册观察者,然后在reverseGeocodeLocation
的completionHandler
内发布通知。您可以通过此 StackOverflow Post 获得更多详细信息。 .
- 使用
关于swift - 如何在闭包中调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42241177/