2

I have built a screen very similar to the Tinder main screen. I have set the borders on the draggable icon and the next card loads by being animated from the top of the screen. At the moment there are 2 buttons (1 accept button, 1 reject button) and when they are pressed the card rotates and transforms out of the screen in the right direction. This function currently accomplishes this animation...

func rejectAnimation() {

    let scale = CGAffineTransformMakeScale(1, 1)
    let translate = CGAffineTransformMakeTranslation(0, 0)
    self.cardUIView.transform = CGAffineTransformConcat(scale, translate)

    springWithCompletion(0.75, animations: {

        let rotate = CGAffineTransformMakeRotation(CGFloat(-M_PI_2))
        let translate = CGAffineTransformMakeTranslation((-375), 0)
        self.cardUIView.transform = CGAffineTransformConcat(rotate, translate)

        }, completion: { finished in 0
            self.refreshView()
    })
}

and

func acceptAnimation() {

    let scale = CGAffineTransformMakeScale(1, 1)
    let translate = CGAffineTransformMakeTranslation(0, 0)
    self.cardUIView.transform = CGAffineTransformConcat(scale, translate)

    springWithCompletion(0.75, animations: {

        let rotate = CGAffineTransformMakeRotation(CGFloat(M_PI_2))
        let translate = CGAffineTransformMakeTranslation(375, 0)
        self.cardUIView.transform = CGAffineTransformConcat(rotate, translate)

        }, completion: { finished in 0
            self.refreshView()
    })
}

My question is this. How can I animate so that when the user drags a card and drops it to the outside the right or left boundaries the card continues to translate off the screen in the direction it was swiped before resetting to a new card?

Note: the springWithCompletion is a function that performs the animations within it over a certain period of time.

Robert Byrne
  • 907
  • 1
  • 9
  • 18
  • for 2018, it's possible the best way to go on this is a `UIViewControllerAnimatedTransitioning` ... full sample https://stackoverflow.com/a/48081504/294884 – Fattie Jan 08 '18 at 18:26

2 Answers2

6

Check this out . Written in swift 4

func beingDragged(_ gestureRecognizer: UIPanGestureRecognizer) {

    xFromCenter = gestureRecognizer.translation(in: self).x
    yFromCenter = gestureRecognizer.translation(in: self).y
    switch gestureRecognizer.state {

    case .began:
        originalPoint = self.center;
        break;

    case .changed:
        let rotationStrength = min(xFromCenter / ROTATION_STRENGTH, ROTATION_MAX)
        let rotationAngel = .pi/8 * rotationStrength
        let scale = max(1 - fabs(rotationStrength) / SCALE_STRENGTH, SCALE_MAX)
        center = CGPoint(x: originalPoint.x + xFromCenter, y: originalPoint.y + yFromCenter)
        let transforms = CGAffineTransform(rotationAngle: rotationAngel)
        let scaleTransform: CGAffineTransform = transforms.scaledBy(x: scale, y: scale)
        self.transform = scaleTransform
        updateOverlay(xFromCenter)
        break;

    case .ended:
        afterSwipeAction()
        break;

    case .possible:break
    case .cancelled:break
    case .failed:break
    }
}

https://github.com/nickypatson/TinderSwipeView

thanks

clemens
  • 16,716
  • 11
  • 50
  • 65
nickypatson
  • 146
  • 2
  • 13
0

Just use UIPanGestureRecognizer and calculate the difference between two points to know which direction to animate (the handler is called several times). If you need to animate both x and y axles at the same time then it gets more complicated.

let panGesture = UIPanGestureRecognizer(target: self, action: Selector("onPan:"))
cardView.addGestureRecognizer(panGesture)

func onPan(gestureRecognizer: UIPanGestureRecognizer) {
    let point = gestureRecognizer.locationInView(maskView)
Tapani
  • 3,191
  • 1
  • 25
  • 41