Ios Can';获取位置后不更新标签

Ios Can';获取位置后不更新标签,ios,swift,core-location,Ios,Swift,Core Location,我有一个简单的按钮,当我按下按钮时,我正在调用另一个类,我的Location类来获取用户的当前位置。 获取位置后,我想更新标签文本,我必须显示位置 这是我的位置类: class LocationManager: NSObject, CLLocationManagerDelegate { var locationManager: CLLocationManager! var geoCoder = CLGeocoder() var userAddress: String? override i

我有一个简单的按钮,当我按下按钮时,我正在调用另一个类,我的Location类来获取用户的当前位置。 获取位置后,我想更新标签文本,我必须显示位置

这是我的位置类:

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())时,什么都不会发生,就像它不会注册点击一样。只有在第二次点击后,我才得到地址和标签的更新。 我尝试添加打印,并使用断点查看第一次点击是否注册,它确实注册了。 我知道该位置可能需要几秒钟才能返回带有地址的答案,我等待了几秒钟,但仍然什么也没有,只是在第二次点击后才显示


似乎在第一次点击时,它还没有找到地址。当我得到地址并试图更新标签时,我如何才能“通知”呢?

因为
didUpdateLocations
&
reverseGeoLocation
方法是异步调用的,这个
guard
可能会从
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 
   }
}

首先,为什么即使
locationServicesEnabled
为false,您仍希望得到结果?问题是
requestLocation()
不是同步的,它不返回任何内容。位置请求的响应在
didUpdateLocations
中异步返回,
ReverseGeoLocation
也异步返回。虽然这绝对不正确,但我认为如果您等待10秒钟,标签将被更新。你的设置类似于是的,我刚刚编辑了我的OP,这就是我在想的,我如何解决这个问题?我不介意在更新之前等待几秒钟,但它需要一次点击。