First, a little context. I was trying to create a simple animation of a view that pulsates indefinitely and found it to be a really frustrating experience, probably because I don’t yet understand the SwiftUI animation model correctly. If someone has a simple solution, please share.
Anyway, it occurred to me that it would be nice to have a view modifier that you attach to a view to express the desire to “animate property X of the view from value ‘from’ to value ‘to’, starting at value ‘startingAt’, using animation ‘animation’. All the view needs to do is expose that property X, as a key path or maybe a binding, and SwiftUI does the rest.
This would allow for an easy way to animate several properties independently but simultaneously, each with their own animation parameters, as well as a way to animate a group of properties together (the view exposes some property which it uses internally to control a group of properties).
Is this something that’s already possible and easy to do? If so, how?
Here’s what the setup above would/might look like in actual code:
struct ContentView: View {
// Note that, in this setup, x, y, and z are all animated independently from
// each other, and with their own custom parameters.
// Properties can be animated together by exposing a single property that
// controls them internally (as 'z' does in the example below).
// All parameters are optional:
// - 'from' defaults to 0
// - 'to' defaults to 1
// - 'startingAt' defaults to 'from'
// - the animation defaults to 'basic()' with its default parameters
// Instead of exposing a key-path, perhaps exposing a binding would make
// more sense and/or be more appropriate.
var body: some View {
SomeView()
// .animating(\.x, from: 0.3, to: 0.8, startingAt: 0.4,
// Animation.basic().repeatForever(autoreverses: true))
// .animating(\.y, from: 5.0, to: 3.0, startingAt: 3.5,
// Some Animation here)
// .animating(\.z, from: 0.25, to: 0.7, startingAt: 0.5,
// Some Animation here)
}
}
struct SomeView: View {
// Some property exposed by SomeView, which some
// aspect of its layout or rendering depends on.
var x: CGFloat = 0
// Some other property exposed by SomeView, which some
// other aspect of its layout or rendering depends on.
var y: Double = 0
// This property is used internally to control several other
// such properties, in essence animating them together.
var z: Double = 0
var body: some View {
Circle()
.fill(Color.red)
}
}