我正在尝试使用 MapKit 和 CoreLocation 制作 SwiftUI 地图应用程序。有一个选项可以让地图随着用户位置的变化而移动(随着蓝色标记的移动而移动)。
我的问题是,随着位置更新(每半秒左右),地图会从前一个位置跳到下一个位置(有加速和停止),而不是线性移动(就像 Apple 地图中的情况一样,如果用户四处移动)。
这是我的视图的代码:
Map(position: $position) {
UserAnnotation()
}
.onReceive(locationManager.$position, perform: { newValue in
withAnimation(.smooth) {
position = newValue
}
})
该位置是来自我的 LocationManager 的已发布值,该值在以下代码中更新:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
self.position = .region(MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude), span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)))
}
我尝试使用
withAnimation
,但它只是使其在一个值和另一个值之间产生动画,但在多个值变化中它仍然不是线性的。
您无需执行自己的位置更新,而是使用提供的
MapCameraPosition
为
userLocation(followsHeading:fallback:)
设置状态变量
这是一个最小的工作示例,显示地图和用户的当前位置。当用户移动时,地图会像主地图应用程序一样平滑地移动。
运行此代码之前,请确保在 Info.plist 中添加适当的位置隐私字符串。
这还包括一个准系统位置管理器类,以便应用程序可以请求用户的位置访问权限。
import MapKit
struct ContentView: View {
// set followsHeading as desired
@State private var position: MapCameraPosition = .userLocation(followsHeading: false, fallback: .automatic)
private var lm = LocationManager()
var body: some View {
Map(position: $position) {
UserAnnotation()
}
}
}
class LocationManager: NSObject, CLLocationManagerDelegate {
private var lm = CLLocationManager()
override init() {
super.init()
lm.delegate = self
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error)
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
switch manager.authorizationStatus {
case .notDetermined:
manager.requestWhenInUseAuthorization()
case .restricted:
print("restricted")
case .denied:
print("denied")
case .authorizedAlways:
print("always")
case .authorizedWhenInUse:
print("in use")
@unknown default:
print("other")
}
}
}