iOS 17 MapKit - 基于位置变化的注释动画

问题描述 投票:0回答:1

如何在 iOS 17 中的 MapKit 中根据位置变化简单地为新注释添加动画效果?在 MK 中,这是很困难的,但我似乎找不到任何与新 MapKit 兼容的东西。

需求:当位置发生变化时,将注释从oldValue平滑动画到newValue。

非常感谢您的帮助。

-d

所以我几乎尝试了所有方法,但最终想到了将 oldValue 和 newValue 之间的增量细分为 100 的想法,然后强力更新每个分数的位置。这是我正在使用的功能:

func animateAnnotationMove(从旧坐标:CLLocationCooperative2D,到新坐标:CLLocationCoordinate2D,步骤:Int = 100,间隔:TimeInterval = 0.05){ 让 latitudeDiff = (新坐标.纬度 - 旧坐标.纬度) / Double(步数) 让 longitudeDiff = (newCooperative.longitude - oldCooperative.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 秒一次)并为增量设置动画。

想法?

animation swiftui annotations mapkit ios17
1个回答
0
投票

这就是我如何将自定义注释设置为动画,包括将注释保持在中心的地图。

@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()
    }
© www.soinside.com 2019 - 2024. All rights reserved.