在 MK 中这是很困难的,但我似乎找不到任何可以与新 MapKit 配合使用的东西。
需求:当位置发生变化时,将注释从
oldValue
平滑动画到newValue
。
所以我几乎尝试了所有方法,但最终想到了将
oldValue
和 newValue
之间的增量细分为 100,然后强力更新每个分数的位置的想法。这是我正在使用的功能:
func animateAnnotationMove(from oldCoordinate: CLLocationCoordinate2D, to newCoordinate: CLLocationCoordinate2D, steps: Int = 100, interval: TimeInterval = 0.05) {
let latitudeDiff = (newCoordinate.latitude - oldCoordinate.latitude) / Double(steps)
let longitudeDiff = (newCoordinate.longitude - oldCoordinate.longitude) / Double(steps)
var currentStep = 0
Timer.scheduledTimer(withTimeInterval: interval, repeats: true) { [weak self] timer in
guard currentStep < steps else {
timer.invalidate() // Stop the timer
return
}
let nextLatitude = oldCoordinate.latitude + (latitudeDiff * Double(currentStep))
let nextLongitude = oldCoordinate.longitude + (longitudeDiff * Double(currentStep))
let nextCoordinate = CLLocaionCoordinate2D(latitude: nextLatitude, longitude: nextLongitude)
DispatchQueue.main.async {
self?.updateGuestAnnotationPosition(with: nextCoordinate)
}
currentStep += 1
}
}
我担心的是,随着我的扩展,这并不是很有效,并且由于 SwiftUI 能够在许多其他领域进行动画处理,也许我错过了一些明显的东西?我的位置数据每 5 秒更新一次,因此这里的想法是将其分解为 100 个函数调用(因此每 0.05 秒一次)并为增量设置动画。
这就是我如何将自定义注释设置为动画,包括将注释保持在中心的地图。
@State private var cameraPosition: MapCameraPosition = .region(MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 0, longitude: 0), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)))
var body: some View {
@State var location: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: plane.lat ?? 0, longitude: plane.lon ?? 0)
@State var region: MKCoordinateRegion = MKCoordinateRegion(center: location, span: MKCoordinateSpan(latitudeDelta: 0.3, longitudeDelta: 0.3))
Map(
position: $cameraPosition,
//initialPosition: .region(region)
interactionModes: [.pan, .zoom]
) {
Annotation(coordinate: location) {
Image(systemName: "airplane")
.rotationEffect(Angle(degrees: (plane.track ?? 0) + -90))
.animation(.easeInOut(duration: 1.5), value: plane.track)
} label: {
Label {
VStack(alignment: .leading) {
Text(plane.desc ?? "")
}
} icon: {
Image(systemName: "airplane")
}
}
}
.onChange(of: plane.lon) {
withAnimation(.smooth(duration: 3.5)) {
location = CLLocationCoordinate2D(latitude: plane.lat ?? 0, longitude: plane.lon ?? 0)
region = MKCoordinateRegion(center: location, span: MKCoordinateSpan(latitudeDelta: 0.3, longitudeDelta: 0.3))
cameraPosition = .region(region)
}
}
.animation(.easeInOut(duration: 0.5), value: location)
.mapControlVisibility(.visible)
.ignoresSafeArea()
}