Search code examples
swiftuiswiftui-animation

Bouncing ball-like animation to draw attention towards a button


I already checked various tutorials and information but cannot put together the last mile.

My code is

struct WelcomeView: View {
    @State private var chevronAnimationRunning = true

    var body: some View {

        Image(systemName: "chevron.down")
            .resizable()
            .scaledToFit()
            .frame(width: 60, height: 60)
            .foregroundColor(.accentColor)
            .offset(y: chevronAnimationRunning ? 0 : 20)
            .animation(
                Animation
                    .interpolatingSpring(
                        stiffness: 350,
                        damping: 15,
                        initialVelocity: 20)
                    .repeatForever(
                        autoreverses: true),
                value: chevronAnimationRunning)
            .onAppear {
                chevronAnimationRunning.toggle()
            }

    }
}

The idea is that the downwards-pointing chevron icon should draw the attention to a "create" button, by always kinda "hopping".

The interpolatingSpring animation basically does the trick by modifying the .offset(y) attribute; the problem is that it doesn't "reset". I think it should "start again" from the initial offset value, but I am not able to accomplish this. The code posted above is already the "second" variant, I initially tried without the helper state variable chevronAnimationRunning being involved.

Thanks for your help y'all!


Solution

  • The autoreverses: parameter of the .repeatForever modifier dictates whether the animation will animate back to its beginning state or if it will simply "reset" without animating back.

    By setting it to be false the animation will reset instead of animating back, and it will look more like an arrow pointing a certain direction rather than just bouncing back and forth.

    .repeatForever(
        autoreverses: false),          // HERE
        value: chevronAnimationRunning
    )
    

    As for your comment, you just need a shared value that .offset and .animation can each access. So, if you didn't want your WelcomeView to know about .chevronAnimationRunning, you could create your own separate view modifier struct and mix .offset and .animation in there.