I'm trying to animate a few different properties on different views. The animations are all using the same Animation
(with the same duration), and they are all driven by the same property. However, I find that they quite quickly go out of sync with each other, and I don't understand why. Here's my code:
import SwiftUI
struct ContentView: View {
@State var isAnimating = false
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 8, style: .continuous)
.fill(Color.yellow)
.offset(x: isAnimating ? -30 : 0)
.rotationEffect(isAnimating ? .degrees(-10) : .zero)
RoundedRectangle(cornerRadius: 8, style: .continuous)
.fill(Color.green.opacity(0.5))
.offset(x: isAnimating ? 30 : 0)
.rotationEffect(isAnimating ? .degrees(10) : .zero)
RoundedRectangle(cornerRadius: 8, style: .continuous)
.fill(Color.red)
.scaleEffect(isAnimating ? 1.1 : 1)
}
.frame(width: 100, height: 100)
.padding()
.onAppear {
let animation = Animation.bouncy(duration: 0.5)
.repeatForever(autoreverses: true)
withAnimation(animation) {
isAnimating = true
}
}
}
}
#Preview {
ContentView()
}
The only workaround I've found is to use a different Animation
than Animation.bouncy
, e.g. Animation.linear
or Animation.easeInOut
. In that case, the animations all stay in sync. That leads me to believe that this is related to Animation.bouncy
somehow (other springy animations exhibit the same problem, e.g. Animation.spring
).
This problem occurs in SwiftUI previews, on device, and on the iOS simulator (all using the latest software as of writing: iOS 17.4, Xcode 15.3).
Video: https://imgur.com/a/btVESSG
A workaround would be to go with
Animation.interpolatingSpring(duration: 0.5)
Since.bouncy
is a customized spring animation, you can use interpolatingSpring and achieve the desired result
Per the docs:
An interpolating spring animation that uses a damped spring model to produce values in the range [0, 1] that are then used to interpolate within the [from, to] range of the animated property. Preserves velocity across overlapping animations by adding the effects of each animation.