Home > Software engineering >  SwiftUI's new animation method only works combined with onTapGesture
SwiftUI's new animation method only works combined with onTapGesture

Time:08-15

I am trying to animate an arrow to make it flip 180 degrees when a button is tapped. But it only works when I use the onTapGesture method with nothing else inside. It also does not work if I change the rotation angle value somewhere else in the code. For instance:

This piece of code is properly animated

Image(systemName: "arrow.up.circle")
                                .resizable()
                                .foregroundColor(.white)
                                
                                .frame(width: 50, height: 50)

                                .rotationEffect(Angle.degrees(self.rotationAngle))
                                .animation(.easeIn, value: self.rotationAngle)
                                .onTapGesture {
                                    self.rotationAngle  = 180

                                }

This one is not

  Image(systemName: "arrow.up.circle")
                                .resizable()
                                .foregroundColor(.white)
                                
                                .frame(width: 50, height: 50)

                                .rotationEffect(Angle.degrees(self.rotationAngle))
                                .animation(.easeIn, value: self.rotationAngle)
                                .onTapGesture {
                                    self.currentArrow.toggle()
                                    self.rotationAngle  = 180
                                }

Does anyone know why?

CodePudding user response:

The .animation(.easeIn, value: self.rotationAngle) modifier explicitly tells the view to animate when self.rotationAngle changes.

However, there's no such instruction for the currentArrow property changes, so the view doesn't animate when it changes.

To fix it, you can do either of two things:

A. Add a similar modifier for the currentArrow property:

.animation(.easeIn, value: currentArrow)

B. Toggle the value within a withAnimation block:

withAnimation {
    self.currentArrow.toggle()
}

CodePudding user response:

Answer: As @vadim-belyaev mentioned, using withAnimation will fix the animation but it only works if nothing else is inside the block. This will happen similarly with onTapGesture My solution is as follows:

Image(systemName: "arrow.up.circle")
                                .resizable()
                                .foregroundColor(.white)
                                
                                .frame(width: 50, height: 50)

                                .rotationEffect(Angle.degrees(self.rotationAngle))
                                .animation(.easeIn, value: self.rotationAngle)
                                .onTapGesture {
                                    withAnimation {
                                        self.rotationAngle  = 180

                                    }
                                }
                        
  • Related