SwiftUI:创建显式动画

您已经了解了SwiftUI如何通过将animation()修饰符附加到视图来创建隐式动画,以及它如何通过将animation()修饰符添加到绑定来创建动画,但是,还有第三种有用的方法可以创建动画:显式地要求SwiftUI设置状态改变来产生动画。

这仍然不意味着我们手工创建动画的每一帧——这仍然是SwiftUI的工作,它通过查看应用状态更改前后视图的状态来继续计算动画。

不过,现在我们明确表示,我们希望在发生任意状态更改时发生动画:它没有附加到绑定,也没有附加到视图,只是我们明确要求由于状态更改而发生特定动画。

为了演示这一点,让我们再次回到一个简单的按钮示例:

struct ContentView: View {   
    var body: some View {
        Button("Tap Me") {
            // do nothing
        }
        .padding(50)
        .background(Color.red)
        .foregroundColor(.white)
        .clipShape(Circle())
    }
}

当这个按钮被点击时,我们将使它以3D效果旋转。这需要另一个新的修改器rotation3dfeffect(),它可以给定以度为单位的旋转量以及确定视图旋转方式的轴。把这条轴想象成一个从你的视野中穿过的斜线:

  • 如果我们通过X轴扭曲视图(水平),那么它将能够前后旋转。
  • 如果我们通过Y轴(垂直)扭曲视图,那么它将能够左右旋转。
  • 如果我们通过Z轴(深度)扭曲视图,那么它将能够左右旋转。

要使这个工作需要一些我们可以修改的状态,旋转度数被指定为Double。所以,请现在添加此属性:

@State private var animationAmount = 0.0

下一步,我们将要求按钮沿Y轴旋转animationAmount角度,这意味着它将左右旋转。现在将此修饰符添加到按钮:

.rotation3DEffect(.degrees(animationAmount), axis: (x: 0, y: 1, z: 0))

现在重要的一点是:我们将在按钮的操作中添加一些代码,这样每次点击时它都会向animationAmount添加360。

如果我们只写self.animationAmount += 360,那么更改将立即发生,因为按钮没有附加动画修饰符。这就是显式动画的来源:如果我们使用withAnimation()闭包,那么SwiftUI将确保由新状态导致的任何更改都将自动设置动画。

所以,现在把这个放到按钮的Action中:

withAnimation {
    self.animationAmount += 360
}

现在运行这段代码,我想你会对它的外观印象深刻——每次点击按钮,它就会在三维空间中旋转,而且编写起来非常容易。如果你有时间的话,用坐标轴做一点实验,这样你就能真正了解它们是如何工作的。如果你好奇,你可以同时使用多个坐标轴。

withAnimation()可以被赋予一个动画参数,使用所有可以在SwiftUI其他地方使用的相同动画。例如,我们可以使用一个使用withAnimation()调用的弹簧动画来实现旋转效果,如下所示:

withAnimation(.interpolatingSpring(stiffness: 5, damping: 1)) {
    self.animationAmount += 360
}

译自 Creating explicit animations

Previous: 动画绑定 Hacking with iOS: SwiftUI Edition Next: 控制动画堆栈

赏我一个赞吧~~~

你可能感兴趣的:(SwiftUI:创建显式动画)