ios 创建MKMapKit曲面/球面/插值相机过渡

8hhllhi2  于 2023-10-21  发布在  iOS
关注(0)|答案(1)|浏览(118)

我想动画相机,使整个动画感觉“弯曲”,而不是“线性”。
现在,使用iOS提供的开箱即用的相机动画,甚至使用UIView.animate()时,动画感觉就像相机直接从开始移动到结束。然而,我希望动画感觉像是从开始到结束的曲线。
这里有一张图片描述了它现在的感觉和我希望它的感觉。

下面是一个来自韩国应用程序Kakao maps的例子,说明了所需的动画是什么:

目前,我只是使用两个相机动画,以创建一个飞出和飞在效果。当我用curveEaseInOut为MKMapView的相机创建自己的自定义动画时,动画的速度是curvedEaseInOut,但这并不能创建所需的效果。这就产生了不受欢迎的“线性”感觉,如上面的“现在是什么:”图所示

UIView.animate(withDuration: duration*2,
                   delay: 0,
                   options: .curveEaseIn,
                   animations: {
        self.mapView.camera = preRotationCamera
    }) { _ in
        UIView.animate(withDuration: duration*2,
                       delay: 0.1,
                       options: .curveEaseOut,
                       animations: {
            self.mapView.camera = finalCamera
        }, completion: completion)
    }

我认为使用animateKeyframes(withDuration:delay:options:animations:completion:)可能是一种有效的方法。然而,我还没有能够成功地通过一系列坐标与animateKeyframes()动画MKMapView相机-关键帧似乎被忽略,相机只是直接过渡到最终相机。
例如,以下代码只是将相机直接转换为finalCamera:

UIView.animateKeyframes(withDuration: duration*2, delay: 0, options: .calculationModeCubic, animations: {
        UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.5) {
            self.mapView.camera = preRotationCamera
        }
        UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) {
            self.mapView.camera = finalCamera
        }
    })

如何为iOS创建这种球形/插值/曲面相机过渡?
这是在iOS 15和Swift 5上。

0qx6xfy6

0qx6xfy61#

好吧,这现在可以在SwiftUI中使用“mapCameraKeyframeAnimator”!
如WWDC 23的Wind your way through advanced animations in SwiftUI中所述。
下面是一些示例代码:

struct RaceMap: View {
    let route: Route

    @State private var trigger = false

    var body: some View {
        Map(initialPosition: .rect(route.rect)) {
            MapPolyline(coordinates: route.coordinates)
                .stroke(.orange, lineWidth: 4.0)
            Marker("Start", coordinate: route.start)
                .tint(.green)
            Marker("End", coordinate: route.end)
                .tint(.red)
        }
        .toolbar {
            Button("Tour") { trigger.toggle() }
        }
        .mapCameraKeyframeAnimation(trigger: playTrigger) { initialCamera in
            KeyframeTrack(\MapCamera.centerCoordinate) {
                let points = route.points
                for point in points {
                    CubicKeyframe(point.coordinate, duration: 16.0 / Double(points.count))
                }
                CubicKeyframe(initialCamera.centerCoordinate, duration: 4.0)
            }
            KeyframeTrack(\.heading) {
                CubicKeyframe(heading(from: route.start.coordinate, to: route.end.coordinate), duration: 6.0)
                CubicKeyframe(heading(from: route.end.coordinate, to: route.end.coordinate), duration: 8.0)
                CubicKeyframe(initialCamera.heading, duration: 6.0)
            }
            KeyframeTrack(\.distance) {
                CubicKeyframe(24000, duration: 4)
                CubicKeyframe(18000, duration: 12)
                CubicKeyframe(initialCamera.distance, duration: 4)
            }
        }
    }
}

相关问题