You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何观察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
                }
            }
    }
}

原理说明

  1. 当你在主视图中通过withAnimation修改targetRotation时,SwiftUI会自动驱动RotatingView的animatableData属性从当前值平滑过渡到目标值。
  2. animatableData的setter会在动画的每一帧被调用,因此rotationDegrees会实时更新为当前的插值。
  3. 借助onChange(of: rotationDegrees),就能捕捉到动画过程中的每一个中间值。

为什么原有方法无效

  • @State变量的更新是原子性的,在withAnimation闭包中修改时,它会直接被设置为最终目标值,动画效果是SwiftUI在渲染层面单独处理的,并不会同步更新@State变量的中间值。
  • animatedData是UIKit时代的API,并不适用于SwiftUI的动画系统,所以无法获取到插值。

内容的提问来源于stack exchange,提问作者Deniz Eroglu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 17:35:24