Throwing paper/ball animation effect in SwiftUI

Hi,

What would be the best animation method in SwiftUI to reproduce the UIKit animation shown below?

What I need is basically a throwing effect starting from point A and ending at Point B. I don't need any bouncing effects, this is more of an effect to let the user know that something was added from point A to Point B; similar to the effect we get when we add a photo to an album in Photos.

I tried using .rotationEffect() but the animation I get is too circular and with no option to add the point locations. I need a more natural throwing-paper-like animation where you define three points, start, apex and end, see the image below.

Please note that Point A and Point B will be some views on the screen and the throwing object will be a simple SF symbol Image(systemName: "circle.fill").

Any suggestions?

What I have tried in SwiftUI that cannot make it look like a throwing paper animation.

struct KeyframeAnimation: View {
    @State private var ascend = false
    @State private var ascendDescend = false
    @State private var descend = false
    
    var body: some View {
        ZStack{
            VStack{
                ZStack{
                    Image(systemName: "circle.fill")
                        .font(.title)
                        .offset(x: -157)
                        .foregroundColor(Color.red)
                        .rotationEffect(.degrees(ascend ? 17: 0))
                        .rotationEffect(.degrees(ascendDescend ? 145: 0))
                        .rotationEffect(.degrees(descend ? 18: 0))
                        .onAppear{
                            withAnimation(Animation.easeInOut(duration: 0.5)){
                                self.ascend.toggle()
                            }
                            
                            withAnimation(Animation.easeInOut(duration: 1)){
                                self.ascendDescend.toggle()
                            }
                            withAnimation(Animation.easeInOut(duration: 2).delay(8)){
                                self.descend.toggle()
                            }
                        }
                }
            }
        }
    }
}

UIKit Animation

This is what I need.

@IBAction func startAnimation(_ sender: Any) {
    UIView.animateKeyframes(withDuration: 3.0, delay: 0.0, options: [.calculationModeCubic], animations: {
        // start
        UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1.0/5.0, animations: {
            self.myView.center =  CGPoint(x: self.pointA.center.x, y: self.pointA.center.y)
        })
        // apex
        UIView.addKeyframe(withRelativeStartTime: 1.0/5.0, relativeDuration: 1.0/5.0, animations: {
            self.myView.center =  CGPoint(x: self.pointB.center.x - 100, y: self.pointB.center.y - 100)
        })
        // end
        UIView.addKeyframe(withRelativeStartTime: 2.0/5.0, relativeDuration: 1.0/5.0, animations: {
            self.myView.center =  CGPoint(x: self.pointB.center.x, y: self.pointB.center.y)
        })
    }
    )
}

I gave up after spending a lot of time trying to do the animation in SwfitUI and ended up reusing the existing UIKit animation using a UIViewRepresentable as suggested in the following thread.

http://stackoverflow.com/questions/70553786/animating-a-swiftui-view-with-uiview-animate/70645853#70645853/

   import SwiftUI

    struct WrapUIKitAnimationInSwiftUI: View {
        @State private var isAnimating = false
        var body: some View {
            HStack{
                Image(systemName: "circle.fill")
                    .font(.system(size: 65))
                    .foregroundColor(.blue)
                    .throwAnimation(isAnimating: $isAnimating)
                    .onTapGesture {
                        isAnimating.toggle()
                    }
            }
        }
    }


    struct ThrowAnimationWrapper<Content: View>: UIViewRepresentable{
        @ViewBuilder let content: () -> Content
        @Binding var isAnimating: Bool
        func makeUIView(context: Context) -> UIView {
            UIHostingController(rootView: content()).view
        }
        func updateUIView(_ uiView: UIView, context: Context) {
            if isAnimating{
                UIView.animateKeyframes(withDuration: 1.5, delay: 0.0, options: [.calculationModeCubic], animations: {
                    UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.2, animations: {
                        uiView.center =  CGPoint(x: 250, y: 300)
                    })
                    UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.9, animations: {
                        uiView.center =  CGPoint(x: 100 + 75, y: 100 - 50 )
                        uiView.transform = CGAffineTransform(scaleX: 0.75, y: 0.75)
                    })
                    
                    UIView.addKeyframe(withRelativeStartTime: 0.1, relativeDuration: 0.7, animations: {
                        uiView.center =  CGPoint(x: 100, y: 100)
                        uiView.transform = CGAffineTransform(scaleX: 0.2, y: 0.2)
                    })
                }, completion: { _ in
                    uiView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
                })
            }
        }
    }

    extension View {
        func throwAnimation( isAnimating: Binding<Bool>) -> some View {
            modifier(ThrowAnimationViewModifier(isAnimating: isAnimating))
        }
    }
    struct ThrowAnimationViewModifier: ViewModifier {
        @Binding var isAnimating: Bool
        func body(content: Content) -> some View {
            ThrowAnimationWrapper(content: {
                content
            }, isAnimating: $isAnimating)
        }
    }
Throwing paper/ball animation effect in SwiftUI
 
 
Q