SwiftUI中CLLocationDistance返回异常巨大值问题求助
高尔夫APP中CLLocation计算距离异常巨大的问题修复
问题描述
开发高尔夫APP时遇到以下问题:使用CLLocation计算两点距离,控制台打印的坐标正确且两点位置极近,但返回的CLLocationDistance值却异常巨大(如9582674.806)。
APP逻辑:在ClubDetailView中,点击「Swing Location」按钮获取用户位置并设为shotCoord,按钮切换为「Ball Location」;再次点击按钮获取位置设为ballCoord,随后计算两者距离。使用iPad的Swift Playgrounds开发,获取的是实际设备位置。
原因分析
- 核心问题:点击「Swing Location」按钮时,仅调用了
getShotLocation()获取位置,但没有将获取到的位置赋值给绑定的shotCoord变量。计算距离时使用的shotCoord是其初始值(通常是经纬度为0,0的位置,位于大西洋中部),和实际的ballCoord计算自然会得到超大距离。 - 次要问题:
LocationManagerModel的requestAllowOnceLocationPermission方法中,调用requestLocation后立刻执行stopUpdatingLocation,可能导致位置还未完成更新就被停止,拿到的lastLocation可能是旧值或初始值。
修复方案(尽量少修改代码)
1. 修复shotCoord赋值问题
修改ClubDetailView中「Swing Location」按钮的action代码,将获取到的位置赋值给绑定的shotCoord:
if self.waiting == false{ Button(action: { let shotCoords = getShotLocation() print("shotCoords = \(shotCoords)") // 新增:将获取到的位置赋值给绑定的shotCoord self.shotCoord = shotCoords self.waiting = true }, label: { Text("Swing Location") .foregroundColor(.white) .font(.system(.title, design: .rounded, weight: .bold)) .frame(maxWidth: .infinity) }) .buttonStyle(.borderedProminent) }
2. 修复位置更新被提前停止的问题
修改LocationManagerModel中的requestAllowOnceLocationPermission方法,移除立刻停止更新的代码(requestLocation本身就是单次位置请求,无需手动停止):
func requestAllowOnceLocationPermission() { locationManager.requestLocation() // 移除这行代码:locationManager.stopUpdatingLocation() }
3. 可选:添加位置非空校验(避免强制解包崩溃)
在getShotLocation和getBallLocation方法中添加非空校验,避免lastLocation为nil时崩溃:
func getShotLocation() -> CLLocation { locationManager.requestAllowOnceLocationPermission() // 简单等待位置更新(实际可结合异步回调优化) while locationManager.lastLocation == nil { RunLoop.current.run(until: Date().addingTimeInterval(0.1)) } return locationManager.lastLocation! } func getBallLocation() -> CLLocation { locationManager.requestAllowOnceLocationPermission() while locationManager.lastLocation == nil { RunLoop.current.run(until: Date().addingTimeInterval(0.1)) } return locationManager.lastLocation! }
验证修改
修改后,点击「Swing Location」会将实际获取的位置赋值给shotCoord,再次点击「Ball Location」时,用两个实际获取的近距位置计算距离,就能得到正常的数值(单位是米,可自行转换为码:1码≈0.9144米)。
内容的提问来源于stack exchange,提问作者jhbetts
相关产品推荐
相关产品推荐

