I'm exploring a sine wave rendering in a SwiftUI View, and have built my view to have 3 controllable parameters:
phase(to control the offset and allow animating "horizontally")amplitude(to control how high each peak is)frequency(how many complete waves there are)
Here's a screenshot:
My SineWave is implemented as a Shape, so it is already Animatable. I made amplitude and frequency an AnimatablePair and expose it as my shape's animatable data like this:
var animatableData: AnimatablePair<CGFloat, CGFloat> {
get { .init(frequency, amplitude) }
set {
frequency = newValue.first
amplitude = newValue.second
}
}
This works, and I get a nice animation if I do this in my containing view:
SineWaveShape(phase: phase, amplitude: amplitude, frequency: frequency)
.stroke(style: StrokeStyle(lineWidth: 3, lineCap: .round, lineJoin: .round))
.foregroundColor(.red)
.onAppear {
withAnimation(Animation.spring(response: 0.5, dampingFraction: 0.4, blendDuration: 0.1).repeatForever()) {
amplitude = 0.1
frequency = 4
}
}
Now I want to animate the phase as well. But I don't want this one to auto-reverse, and I want it to be much faster. Unfortunately adding another withAnimation block next to this one has no effect, even if I have it as part of my animatable data. The last animation block always wins.
How should I approach this problem of wanting to animate two properties with two different Animation instances?
