Swift - Tinder effect

前端 未结 4 1802
醉酒成梦
醉酒成梦 2020-12-29 00:02

How can I achieve Tinder effect in Swift?

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

I can do it with the

相关标签:
4条回答
  • 2020-12-29 00:13

    It's better to use UIPanGestureRecognizer here and manage its states, as you've already figured out. For managing cards it would be good solution to create class-manager that will handle interactions between cards(moving background cards on swiping the front). You can look at the implementation of card and manager here, there are implementation of dragging, moving background cards and revert animations. https://github.com/Yalantis/Koloda

    0 讨论(0)
  • 2020-12-29 00:18

    Try this:

    https://github.com/cwRichardKim/TinderSimpleSwipeCards

    You can find a better solution here with rotation. See DraggableView.m

    -(void)beingDragged:(UIPanGestureRecognizer *)gestureRecognizer
    {
        //%%% this extracts the coordinate data from your swipe movement. (i.e. 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's 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 讨论(0)
  • 2020-12-29 00:24

    I would like to thanks the people who suggested solutions. Follow the solution I developed with a huge help of a lot of 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 - to be accepted or rejected

    LbResultado --> UITextView - to show the user he is in acceptance or rejection area

    There is no math calculations to set rotation and translation. I used values that give me a visually good effect.

    The action (acceptance and rejection) area is when the user drag image more than 100 pixels to left (reject) or right (accept). If the user ends the movement out the action area, the image will go back to its original position.

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

    0 讨论(0)
  • 2020-12-29 00:35

    Check this out 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 will work . Let me know

    https://github.com/nickypatson/TinderSwipeView

    thanks

    0 讨论(0)
提交回复
热议问题