Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI withAnimation completion callback

I have a swiftUI animation based on some state:

withAnimation(.linear(duration: 0.1)) {     self.someState = newState } 

Is there any callback which is triggered when the above animation completes?

If there are any suggestions on how to accomplish an animation with a completion block in SwiftUI which are not withAnimation, I'm open to those as well.

I would like to know when the animation completes so I can do something else, for the purpose of this example, I just want to print to console when the animation completes.

like image 565
Kris Gellci Avatar asked Sep 03 '19 00:09

Kris Gellci


1 Answers

On this blog this Guy Javier describes how to use GeometryEffect in order to have animation feedback, in his example he detects when the animation is at 50% so he can flip the view and make it looks like the view has 2 sides

here is the link to the full article with a lot of explanations: https://swiftui-lab.com/swiftui-animations-part2/

I will copy the relevant snippets here so the answer can still be relevant even if the link is not valid no more:

In this example @Binding var flipped: Bool becomes true when the angle is between 90 and 270 and then false.

struct FlipEffect: GeometryEffect {      var animatableData: Double {         get { angle }         set { angle = newValue }     }      @Binding var flipped: Bool     var angle: Double     let axis: (x: CGFloat, y: CGFloat)      func effectValue(size: CGSize) -> ProjectionTransform {          // We schedule the change to be done after the view has finished drawing,         // otherwise, we would receive a runtime error, indicating we are changing         // the state while the view is being drawn.         DispatchQueue.main.async {             self.flipped = self.angle >= 90 && self.angle < 270         }          let a = CGFloat(Angle(degrees: angle).radians)          var transform3d = CATransform3DIdentity;         transform3d.m34 = -1/max(size.width, size.height)          transform3d = CATransform3DRotate(transform3d, a, axis.x, axis.y, 0)         transform3d = CATransform3DTranslate(transform3d, -size.width/2.0, -size.height/2.0, 0)          let affineTransform = ProjectionTransform(CGAffineTransform(translationX: size.width/2.0, y: size.height / 2.0))          return ProjectionTransform(transform3d).concatenating(affineTransform)     } } 

You should be able to change the animation to whatever you want to achieve and then get the binding to change the state of the parent once it is done.

like image 158
dev_jac Avatar answered Sep 20 '22 02:09

dev_jac