如何在SwiftUI的CGAffineTransform上为RotationAngle添加动画?

时间:2019-09-18 23:20:07

标签: swift swiftui cgaffinetransform

我需要使用rotationAngle为CGAffineTransform设置动画,但我不知道是否可行,因为CGAffineTransform不符合Animatable。 Maby带有“ withAnimation”,但我不知道如何使用它。我知道我可以使用rotationEffect,但是对于某些存在的理由,我必须使用CGAffineTransform。

我的代码:

ENTRYPOINT node . | tee >(send_logs_to_elastic_search)

1 个答案:

答案 0 :(得分:2)

如果您不能使用任何现有的动画效果,则需要教SwiftUI如何为变换矩阵设置动画。您可以使用GeometryEffect来实现。这是一个同时符合Animatable和ViewModifier的协议。

如果您想全面了解GeometryEffect的工作原理,请查看我的文章:https://swiftui-lab.com/swiftui-animations-part2/

这是一个可行的示例:

struct ContentView: View {
    @State private var animate = false

    var body: some View {
        Rectangle()
            .frame(width: 50, height: 50)
            .modifier(MyEffect(angle: animate ? .pi * 2 : 0))
            .onTapGesture {
                withAnimation(.easeInOut(duration: 2.0)) {
                    self.animate.toggle()
                }
        }
    }
}

struct MyEffect: GeometryEffect {
    var angle: CGFloat

    var animatableData: CGFloat {
        get { angle }
        set { angle = newValue }
    }

    func effectValue(size: CGSize) -> ProjectionTransform {
        return ProjectionTransform(CGAffineTransform(rotationAngle: angle))
    }
}

响应您的注释,您可以将withAnimation与任何变量一起使用,而不仅是布尔值。如果变量最终影响到可设置动画的参数,它将进行动画处理。这是一个示例:

struct ContentView: View {
    @State private var angle: CGFloat = 0

    var body: some View {
        VStack {
            Rectangle()
                .frame(width: 50, height: 50)
                .modifier(MyEffect(angle: angle))

            Button("Go to 0") {
                withAnimation(.easeInOut(duration: 2.0)) {
                    self.angle = 0
                }
            }

            Button("Go to 360") {
                withAnimation(.easeInOut(duration: 2.0)) {
                    self.angle = .pi * 2
                }
            }
        }
    }
}