获取位置后无法更新标签
Can't update label after getting location
我有一个简单的按钮,当我按下按钮时,我正在调用另一个 class,我的位置 class 以获取用户的当前位置。
获取位置后,我想更新必须显示位置的标签文本。
这是我的位置class:
class LocationManager: NSObject, CLLocationManagerDelegate {
var locationManager: CLLocationManager!
var geoCoder = CLGeocoder()
var userAddress: String?
override init() {
super.init()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.activityType = .other
locationManager.requestWhenInUseAuthorization()
}
func getUserLocation(completion: @escaping(_ result: String) -> ()){
if CLLocationManager.locationServicesEnabled(){
locationManager.requestLocation()
}
guard let myResult = self.userAddress else { return }
completion(myResult)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
let userLocation: CLLocation = locations[0] as CLLocation
geoCoder.reverseGeocodeLocation(userLocation) { (placemarks, err) in
if let place = placemarks?.last{
self.userAddress = place.name!
}
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
}
这是我调用方法和更新标签的地方:
func handleEnter() {
mView.inLabel.isHidden = false
location.getUserLocation { (theAddress) in
print(theAddress)
self.mView.inLabel.text = "\(theAddress)"
}
}
我的问题是,当我单击我的按钮(并触发 handleEnter())时,没有任何反应,就像它不会注册水龙头一样。只有在第二次点击它之后,我才会得到地址和标签更新。
我尝试添加打印并使用断点来查看第一次点击是否注册,并且确实如此。
我知道该位置可能需要几秒钟才能 return 回答地址,我等了,但仍然没有,只有在第二次点击后它才会显示。
好像是第一次点击,只是还没有获取到地址。我如何才能 "notify" 在收到地址后尝试更新标签?
由于 didUpdateLocations
和 reverseGeocodeLocation
方法是异步调用的,此 guard
可能 return 自 nil
地址
guard let myResult = self.userAddress else { return }
completion(myResult)
这不会触发更新标签所需的完成,而您需要
var callBack:((String)->())?
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
let userLocation: CLLocation = locations[0] as CLLocation
geoCoder.reverseGeocodeLocation(userLocation) { (placemarks, err) in
if let place = placemarks?.last{
callBack?(place.name!)
}
}
}
然后使用
location.callBack = { [weak self] str in
print(str)
DispatchQueue.main.async { // reverseGeocodeLocation callback is in a background thread
// any ui
}
}
我有一个简单的按钮,当我按下按钮时,我正在调用另一个 class,我的位置 class 以获取用户的当前位置。 获取位置后,我想更新必须显示位置的标签文本。
这是我的位置class:
class LocationManager: NSObject, CLLocationManagerDelegate {
var locationManager: CLLocationManager!
var geoCoder = CLGeocoder()
var userAddress: String?
override init() {
super.init()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.activityType = .other
locationManager.requestWhenInUseAuthorization()
}
func getUserLocation(completion: @escaping(_ result: String) -> ()){
if CLLocationManager.locationServicesEnabled(){
locationManager.requestLocation()
}
guard let myResult = self.userAddress else { return }
completion(myResult)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
let userLocation: CLLocation = locations[0] as CLLocation
geoCoder.reverseGeocodeLocation(userLocation) { (placemarks, err) in
if let place = placemarks?.last{
self.userAddress = place.name!
}
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
}
这是我调用方法和更新标签的地方:
func handleEnter() {
mView.inLabel.isHidden = false
location.getUserLocation { (theAddress) in
print(theAddress)
self.mView.inLabel.text = "\(theAddress)"
}
}
我的问题是,当我单击我的按钮(并触发 handleEnter())时,没有任何反应,就像它不会注册水龙头一样。只有在第二次点击它之后,我才会得到地址和标签更新。 我尝试添加打印并使用断点来查看第一次点击是否注册,并且确实如此。 我知道该位置可能需要几秒钟才能 return 回答地址,我等了,但仍然没有,只有在第二次点击后它才会显示。
好像是第一次点击,只是还没有获取到地址。我如何才能 "notify" 在收到地址后尝试更新标签?
由于 didUpdateLocations
和 reverseGeocodeLocation
方法是异步调用的,此 guard
可能 return 自 nil
地址
guard let myResult = self.userAddress else { return }
completion(myResult)
这不会触发更新标签所需的完成,而您需要
var callBack:((String)->())?
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
let userLocation: CLLocation = locations[0] as CLLocation
geoCoder.reverseGeocodeLocation(userLocation) { (placemarks, err) in
if let place = placemarks?.last{
callBack?(place.name!)
}
}
}
然后使用
location.callBack = { [weak self] str in
print(str)
DispatchQueue.main.async { // reverseGeocodeLocation callback is in a background thread
// any ui
}
}