如何观察SwiftUI视图动画属性的插值变化?
如何在SwiftUI中观察动画过程中rotation属性的插值变化
你的问题核心在于:@State变量在动画过程中并不会实时更新为中间插值,而是直接跳转到最终值,所以onChange只能捕捉到动画结束后的结果。要获取动画过程中的每一步插值,需要借助SwiftUI的Animatable协议来实现。
解决方案:自定义遵循Animatable协议的视图
通过创建一个遵循Animatable协议的自定义视图,让系统在动画过程中实时更新我们需要的旋转角度值,从而捕捉到每一步的插值:
struct RotatingView: View, Animatable { var rotationDegrees: Double // 实现Animatable协议的核心属性,动画过程中系统会持续更新该值 var animatableData: Double { get { rotationDegrees } set { rotationDegrees = newValue } } var body: some View { ZStack { RoundedRectangle(cornerRadius: 20) .fill(Color.blue) Text("Example") .foregroundColor(.white) } .frame(width: 300, height: 300) .rotation3DEffect(Angle(degrees: rotationDegrees), axis: (x: 0, y: 1, z: 0)) .onChange(of: rotationDegrees) { newValue in // 这里可以实时打印动画过程中的每一步插值 print(newValue) } } } // 主视图调用示例 struct ExampleView: View { @State private var targetRotation = 0.0 var body: some View { RotatingView(rotationDegrees: targetRotation) .onTapGesture { withAnimation { targetRotation += 60 } } } }
原理说明
- 当你在主视图中通过
withAnimation修改targetRotation时,SwiftUI会自动驱动RotatingView的animatableData属性从当前值平滑过渡到目标值。 animatableData的setter会在动画的每一帧被调用,因此rotationDegrees会实时更新为当前的插值。- 借助
onChange(of: rotationDegrees),就能捕捉到动画过程中的每一个中间值。
为什么原有方法无效
@State变量的更新是原子性的,在withAnimation闭包中修改时,它会直接被设置为最终目标值,动画效果是SwiftUI在渲染层面单独处理的,并不会同步更新@State变量的中间值。animatedData是UIKit时代的API,并不适用于SwiftUI的动画系统,所以无法获取到插值。
内容的提问来源于stack exchange,提问作者Deniz Eroglu
相关产品推荐
相关产品推荐

