When we first began building animations in SwiftUI, it wasn't obvious how to achieve certain effects. How, for example, would you create a shake animation similar to Robb's?
Most animations in SwiftUI are set up implicitly: we change the value of our view's attributes, and tell SwiftUI that we want this change animated. In this case, however, we don't really want to change the model; the text field should stay in the same place, it should just shake a little.
Here, a boolean set to true triggers an animation, which moves the view by 10 points, and repeats that animation 5 times. As the struct's name might suggest, there is a problem with the code. After the first animation the button's x position will be 10 points to the left, and after the next animation it will be correct again.
Instead of animating our model, we can use a modifier. To be precise, we'll use a GeometryEffect that transforms the view's x position based on a counter, which we expose as animatableData:
To use this, we have to modify our code slightly to track the number of attempts. By increasing this number, the animatable data of our Shake modifier will increase by 1. SwiftUI will interpolate between the old and new value, and animate that change.
In the example above, x will animate from 0 to 10, back to -10, back to 10, and stop at 0 (based on shakesPerUnit = 3 and amount = 10).