ios - 获取位置后无法更新标签

标签 ios swift core-location

我有一个简单的按钮,当我按下按钮时,我正在调用另一个类,我的 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())时,没有任何反应,就像它不会注册点击一样。只有在第二次点击它之后,我才会得到地址和标签更新。 我尝试添加打印并使用断点来查看第一次点击是否注册,并且确实如此。 我知道该位置可能需要几秒钟才能返回带有地址的答案,我一直在等待,但仍然一无所获,只有在第二次点击后才会显示。

好像是在第一次点击的时候,只是还没有得到地址而已。我如何在收到地址后“通知”然后尝试更新标签?

最佳答案

由于 didUpdateLocationsreverseGeocodeLocation 方法是异步调用的,因此此 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 
   }
}

关于ios - 获取位置后无法更新标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56709683/

相关文章:

ios - 使用 NSTimer 更好地验证信标

ios - 如何在没有 ViewControllers 的情况下使用 SwiftUI 获取当前位置?

ios - 在tableView的Section Header中为imageView添加手势

ios - 将 "Final"NSOperation 添加到操作次数不确定的队列中

ios - 在 Xcode 的 Core Data Model 中可以有多个同名反向关系的一对一关系吗?

ios - Swift 1.2 - 将可选类型数组中的元素设置为 nil——传入时不允许吗?

objective-c - iOS获取磁盘上的文件大小

iphone - JSON 解析。值不是以公里为单位

ios - FinishRecordingToOutputFileAt 时使用委托(delegate)传递 URL

IOS - 运行后台任务以使用 swift 更新用户位置