Swift - Tinder Effect

How can I achieve the Tinder effect in Swift?

I mean, I have an image and I want to accept if I swipe to the right and deviate if I swipe to the left.

I can do this with the code below:

@IBAction func SwipeRight(sender: UISwipeGestureRecognizer) { UIView.animateWithDuration(1) { self.Imagem.center = CGPointMake(self.Imagem.center.x - 150, self.Imagem.center.y ) } //other things after acception } 

and

 @IBAction func SwipeLeft(sender: UISwipeGestureRecognizer) { UIView.animateWithDuration(1) { self.Imagem.center = CGPointMake(self.Imagem.center.x + 150, self.Imagem.center.y ) } //other things after rejection } 

But in this way, the user cannot undo the action. I want that if the user moves the distance of the delta from the edge (left or right), an image appears that allows the user now, if he finishes the movement, the action will be performed. Otherwise, the user can, without stopping the movement, return to a greater distance than the delta, and the action will be canceled.

+6
source share
4 answers

I would like to thank the people who proposed the solutions. Follow the solution that I developed with the tremendous help of many people from Stack Overflow:

 @IBAction func Arrastei(sender: UIPanGestureRecognizer) { var origem = CGPoint(x: 0, y: 0) var translation : CGPoint = sender.translationInView(Imagem) var txy : CGAffineTransform = CGAffineTransformMakeTranslation(translation.x, -abs(translation.x) / 15) var rot : CGAffineTransform = CGAffineTransformMakeRotation(-translation.x / 1500) var t : CGAffineTransform = CGAffineTransformConcat(rot, txy); Imagem.transform = t if (translation.x > 100) { LbResultado.textColor = btVerdadeiro.textColor LbResultado.text = btVerdadeiro.text LbResultado.hidden = false } else { if (translation.x < -100) { LbResultado.textColor = btFalso.textColor LbResultado.text = btFalso.text LbResultado.hidden = false } else { LbResultado.hidden = true } } if sender.state == UIGestureRecognizerState.Ended { if (translation.x > 100) { objJogo.Rodada_Vigente!.Responder(true) } else { if (translation.x < -100) { objJogo.Rodada_Vigente!.Responder(false) } else { sender.view.transform = CGAffineTransformMakeTranslation(origem.x, origem.y) sender.view.transform = CGAffineTransformMakeRotation(0) } } } } 

This solution uses:

Imagem - UIImageView - accept or decline

LbResultado โ†’ UITextView - show the user that he is in the reception or rejection zone

No math calculations to set rotation and translation. I used values โ€‹โ€‹that give me a visually good effect.

The scope (acceptance and rejection) is when the user drags the image more than 100 pixels to the left (rejection) or right (accept). If the user finishes moving the scope, the image will return to its original position.

I will be glad if someone suggests improvements to this code.

+12
source

It is better to use the UIPanGestureRecognizer here and manage its states, as you already understood. To manage maps, it would be a good decision to create a manager class that will handle interactions between maps (moving background maps when scrolling the front). You can look at the implementation of the map and the manager here, there is an implementation of drag and drop, moving background maps and returning animations. https://github.com/Yalantis/Koloda

+1
source

Try the following:

https://github.com/cwRichardKim/TinderSimpleSwipeCards

Here you can find the best solution with rotation. See DraggableView.m

 -(void)beingDragged:(UIPanGestureRecognizer *)gestureRecognizer { //%%% this extracts the coordinate data from your swipe movement. (ie How much did you move?) xFromCenter = [gestureRecognizer translationInView:self].x; //%%% positive for right swipe, negative for left yFromCenter = [gestureRecognizer translationInView:self].y; //%%% positive for up, negative for down //%%% checks what state the gesture is in. (are you just starting, letting go, or in the middle of a swipe?) switch (gestureRecognizer.state) { //%%% just started swiping case UIGestureRecognizerStateBegan:{ self.originalPoint = self.center; break; }; //%%% in the middle of a swipe case UIGestureRecognizerStateChanged:{ //%%% dictates rotation (see ROTATION_MAX and ROTATION_STRENGTH for details) CGFloat rotationStrength = MIN(xFromCenter / ROTATION_STRENGTH, ROTATION_MAX); //%%% degree change in radians CGFloat rotationAngel = (CGFloat) (ROTATION_ANGLE * rotationStrength); //%%% amount the height changes when you move the card up to a certain point CGFloat scale = MAX(1 - fabsf(rotationStrength) / SCALE_STRENGTH, SCALE_MAX); //%%% move the object center by center + gesture coordinate self.center = CGPointMake(self.originalPoint.x + xFromCenter, self.originalPoint.y + yFromCenter); //%%% rotate by certain amount CGAffineTransform transform = CGAffineTransformMakeRotation(rotationAngel); //%%% scale by certain amount CGAffineTransform scaleTransform = CGAffineTransformScale(transform, scale, scale); //%%% apply transformations self.transform = scaleTransform; [self updateOverlay:xFromCenter]; break; }; //%%% let go of the card case UIGestureRecognizerStateEnded: { [self afterSwipeAction]; break; }; case UIGestureRecognizerStatePossible:break; case UIGestureRecognizerStateCancelled:break; case UIGestureRecognizerStateFailed:break; } } 
0
source

Check out this Swift 4 library !!

let panGestureRecognizer = UIPanGestureRecognizer (target: self, action: #selector (self.beingDragged)) addGestureRecognizer (panGestureRecognizer)

func beingDragged (_ gestureRecognizer: UIPanGestureRecognizer) {

  xFromCenter = gestureRecognizer.translation(in: self).x yFromCenter = gestureRecognizer.translation(in: self).y switch gestureRecognizer.state { //%%% just started swiping case .began: originalPoint = self.center; break; //%%% in the middle of a swipe 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 } } 

Hope this works. Let me know

https://github.com/nickypatson/TinderSwipeView

thanks

-1
source

Source: https://habr.com/ru/post/971787/


All Articles