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
}
}