Search code examples
iosswiftuiswiftui-animation

Bounce animation is working only after second tap [SwiftUI]


I am triggering animation after unhiding the view unfortunately animation is not working unless I tap twice

   struct ContentView: View {

    @State var animate = false
    @State var isViewHidden: Bool = true
    
    var body: some View {
        VStack {
            ZStack {
                    Circle()
                        .fill(.blue).opacity(0.25).frame(width: 40, height: 40).offset(y: self.animate ? 0 : 60)
                        .hides(isViewHidden)
                }
                .animation((Animation.linear(duration: 1.5).repeatForever(autoreverses: true))
                           , value: self.animate ? 0 : 60)
            Spacer()
            Button("Tap here") {
                self.isViewHidden = false
                self.animate.toggle()
            }
        }
        .padding()
    }
}

extension View {
    @ViewBuilder
    func hides(_ isHidden: Bool) -> some View {
        if isHidden {
            hidden()
        } else {
            self
        }
    }
}

Solution

  • SwiftUI uses a before view and an after view to animate. You are introducing the view to animate at the same time you are updating self.animate, so Swift doesn't have a before view to use for the animation.

    Change your View extension to this:

    extension View {
        @ViewBuilder
        func hides(_ isHidden: Bool) -> some View {
            self.opacity(isHidden ? 0 : 1)
        }
    }
    

    This leaves the view onscreen at all times, but just hides it by making it invisible. That way, the view is there to animate from the start.