SwiftUI:您可以动画化数据本身的变化,而不仅仅是视图对变化的响应吗?

时间:2020-08-02 10:43:44

标签: swift animation swiftui

是否可以仅对属性从值a到值b的变化进行动画处理,而不仅仅是为视图对属性更改的响应设置动画?

例如,想象一下点击一个按钮可以使属性增加10,尽管在动画持续时间内,每次渲染视图时,应用都会按照时序曲线更新属性,而不是立即进行更改。

struct ExampleView: View {
    
    @State private var exampleNumber: Double = 0.0 {
        didSet {
            print("New value is \(exampleNumber)")
        }
    }
    
    var body: some View {
        
        VStack {
            Text("Number: \(exampleNumber)")
            
            Button(action: {
                withAnimation(.easeInOut) {
                    exampleNumber += 10.0
                }
            }, label: {
                Text("Smoothly add 10")
            })
        }
    }
}

要清楚,它是我要设置动画的原始属性的值,而不仅仅是视图中显示的值。因此,例如,在60fps的设备上,“ {New value is ...”(新值是...)打印方法将在每秒打印.easeInOut时序曲线的新值时进行60次。

对于Animatable或亲戚来说,这似乎是可行的,但我似乎还无法使其正常工作。预先感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

这里是可能方法的演示。经过Xcode 12 / iOS 14的测试

demo

struct DemoAnimatingNumber: View {
    @State private var number = Double.zero

    var body: some View {
        Rectangle().fill(Color.yellow)
            .frame(maxWidth: .infinity, maxHeight: 60)
            .modifier(AnimatingNumber(number: number))
            .animation(Animation.easeInOut(duration: 2), value: number)
            .onTapGesture {
                number = number == Double.zero ? 10 : Double.zero
            }
    }
}

struct AnimatingNumber: AnimatableModifier {
    var number: Double

    var animatableData: Double {
        get { number }
        set { number = newValue }
    }

    func body(content: Content) -> some View {
        content.overlay(
            Text("Number: \(number, specifier: "%.1f")")
                .foregroundColor(.blue)
        )
    }
}