How to Make Tinder-like Swipe Gesture for iOS

Swipe Slider For iOS

Tinder app is famous for its outstanding UI Animations. It set new trends on the swipeable deck of cards. This kind of layout has advantages in many areas like dating apps, entertainment apps and the other apps where you will show list-type information. Even apple is using this style of animation for its bookmarks management. What’s the best thing about this layout? Yeah, I can say it’s simple, pretty and gives user great flexibility to interact. What else we want? Of course, that’s what a customer loves in your app apart from the content.

The reward is always a happy thing everyone wants. The final reward for following this tutorial will look like below.

Tinder-like Swipe Slider For iOS

We are building our application with XCode 8.3 and Swift 3.0.

In this tutorial, you are going to sail with me on a voyage named “Tinder-like Swipe gesture animation”. We are not going to use Any third-party library here. Even though there are lot’s of libraries outside, we do not prefer that option as if you use the library the customization of it becomes very difficult. Another point to avoid it because you won’t understand what’s happening inside this library. That’s why we will create our own. We will try to cover every step of making swipe gesture animation. Are you ready? Let’s start our engine first.

For better understanding of the concept, we will implement this feature in our app by following steps.

1

Creating swipeable card

2

Moving & resetting of cards position

3

Fade-in & Fade out animation of like & dislike

4

Tilting of card

5

Other customizations

1. Creating swipeable card

Open your Xcode and take new template called ‘Single View Application’. Go to storyboard and drag & drop UIView on view controller. From now on, we are going to refer this view as Card. Now add imageview with your favorite image. Add some dummy text labels on top of it. It’s completely upto you how you are customizing your card layout. Connect your card using IBOutlet. We need this outlet as we are going to apply position changes of the card using it. I’m adding corner radius of 8 to my card layout. Now drag & drop Pan gesture recognizer on top of card view. Pan gesture is going to be superhero here, as most of the work involves with it only. The responsibility of moving card view is entirely on the shoulder of pan gesture. Create IBAction for pan gesture. So whenever you are touching on cardview and trying to move this IBAction method will be called.

In the pan Gesture method, the sender is of type UIPanGestureRecognizer. The sender has a property named ‘view’ which is nothing but the view the pan gesture attached to. Here in our case, it’s card view. Now get translation point from the sender. What is translation point? The translation gives us CGPoint value which tells us how far we moved an object from (x, y) position. This (x, y) position is the previous position of the view. So If I move a card from one location to another location, it gives me (X, Y) values, saying that I have moved X distance from my previous position in the horizontal direction and Y distance from my previous position in the vertical direction. So this point gives me how far I moved my finger from touching down on the view.

We got translation point. How we are going to use it?. If I give this translation point to my card view center, the center is going to change it’s position along with swiping gesture. You got it right. Now define position for you card center like below.

cardView.center = CGPoint(x: view.center.x+translationPoint.x, y: view.center.y+translationPoint.y)
Tinder-like Swipe

Here we are moving card center with reference to it’s superview center, i.e, view.center. By this time your code in ViewController.m file looks like below:

import UIKit  
class ViewController: UIViewController {  
    @IBOutlet weak var cardView: UIView!  
    override func viewDidLoad() {  
        super.viewDidLoad()  
    }  
    @IBAction func panGestureValueChanged(_ sender: UIPanGestureRecognizer) {  
        let cardView = sender.view!  
        let translationPoint = sender.translation(in: view)  
        cardView.center = CGPoint(x: view.center.x+translationPoint.x, y: view.center.y+translationPoint.y)  
    } 
}  
Tinder-like Swipe

Now you can move your card along the direction of your pan gesture. Now move to step 2.

2. Moving & resetting of cards position

The card we move is sticking to its location now. But the swipeable tinder layout has that bouncing effect until you move up to margin, it will bounce back to its center. When we move card after the margin, it will be swiped out off the screen. For this to happen, we have to understand how the user is behaving with the card. In other words, we want pan gesture state of whether user started dragging or end up with dragging. Whenever user ends dragging we are going to check if it’s crossed the margin and based on that we are going to decide to swipe off.

if sender.state == UIGestureRecognizerState.ended {  
    if cardView.center.x < 20 { // Moved to left  
        UIView.animate(withDuration: 0.3, animations: {  
            cardView.center = CGPoint(x: cardView.center.x-200, y: cardView.center.y)  
        })  
        return  
    }  
    else if (cardView.center.x > (view.frame.size.width-20)) { // Moved to right  
        UIView.animate(withDuration: 0.3, animations: {  
            cardView.center = CGPoint(x: cardView.center.x+200, y: cardView.center.y)  
        })  
        return  
    }  
      
    UIView.animate(withDuration: 0.2, animations: {  
        cardView.center = self.view.center  
    })  
}
Tinder-like Swipe

Add above code snippet in the bottom of pan gesture action method. Now we will see what’s happening here. We are checking if cardView center is less than margin(here 20) and moving it off the screen when it crosses the margin. The last three lines will be executed if the view is within limits of margin. At that time, we are resetting it back to center. This gives a bouncing kind of effect for the card layout. By the end of this, you can see a bouncing view which bounces within margins and swipes out of the screen if crosses margin.

3. Fade-in & Fade out animation of like & dislike

To represent like & dislike, I’m going to add emojis on top of it. If you drag the card to the right, we will show smile emoticon whereas if we drag the card to the left we show sad emoticon. We aim to fade in and fade out these emojis as the card moving along user swiping it. You can add these emojis using UIImageview on top of card view in the storyboard. Add IBOutlets connections for these image views. Initially set alpha values of images to 0. Later, to make them visible, we are going to set alpha values for these on the fly. Add below code in gesture method:

let distanceMoved = cardView.center.x - view.center.x  
if distanceMoved > 0 { // moved right side  
    smileImageView.alpha = abs(distanceMoved)/view.center.x  
    sadImageView.alpha = 0  
}  
else { // moved left side  
    sadImageView.alpha = abs(distanceMoved)/view.center.x  
    smileImageView.alpha = 0  
}
Tinder-like Swipe

Find out the distance moved from the center of the screen while swiping. Based on this we can figure out whether user moved to the right or left. From the below line we will get distance moved concerning center of view controller’s main view.

let distanceMoved = cardView.center.x - view.center.x
Tinder-like Swipe

Above code going to give that value. If that value is in -negative, that indicates we moved it left. If the value is +positive(greater than zero), that indicates we moved it to right side.

We are changing alpha value of the image concerning distance the card moved. Now the output shows fade in and fades out of the views. Wait a minute; we are not yet finished with this step. When cardview bounces back to its original position, the alpha values of emojis should be zero. To do that add these lines of code:

self.sadImageView.alpha = 0  
self.smileImageView.alpha = 0 
Tinder-like Swipe

Below this line

cardView.center = self.view.center
Tinder-like Swipe

This is how whole IBAction method of pan gesture looks like.

@IBAction func panGestureValueChanged(_ sender: UIPanGestureRecognizer) {  
    let cardView = sender.view!  
    let translationPoint = sender.translation(in: view)  
    cardView.center = CGPoint(x: view.center.x+translationPoint.x, y: view.center.y+translationPoint.y)  
      
    let distanceMoved = cardView.center.x - view.center.x  
    if distanceMoved > 0 { // moved right side  
        smileImageView.alpha = abs(distanceMoved)/view.center.x  
        sadImageView.alpha = 0  
    }  
    else { // moved left side  
        sadImageView.alpha = abs(distanceMoved)/view.center.x  
        smileImageView.alpha = 0  
    }  
      
    if sender.state == UIGestureRecognizerState.ended {  
        if cardView.center.x < 20 { // Moved to left  
            UIView.animate(withDuration: 0.3, animations: {  
                cardView.center = CGPoint(x: cardView.center.x-200, y: cardView.center.y)  
            })  
            return  
        }  
        else if (cardView.center.x > (view.frame.size.width-20)) { // Moved to right  
            UIView.animate(withDuration: 0.3, animations: {  
                cardView.center = CGPoint(x: cardView.center.x+200, y: cardView.center.y)  
            })  
            return  
        }  
          
        UIView.animate(withDuration: 0.2, animations: {  
            cardView.center = self.view.center  
            self.sadImageView.alpha = 0  
            self.smileImageView.alpha = 0  
        })  
    }  
}
Tinder-like Swipe

We are almost reached our seashore. Now you have customized card view with moving around and bouncing it back to its original position. We will take one more step to make this card view looks much better.

4. Tilting of card

When the user swipes the card layout if we tilt along the swiping direction, it gives the user great feel of swiping. For the rotation of the card, we are taking help of another friend named CGAffineTransform. He is also going to join with us on our voyage. Transform is different from translation point, previously we have seen. Transform allows you to rotate, add scaling(or zooming in & out). When the user moves away from the center to right side, I want to tilt or rotate the card to 35°. Same way when the user moves away from the center to left side, rotate the cardview to 35° . To do this we will call rotate method on CGAffineTransform.

cardView.transform = CGAffineTransform(rotationAngle: 0.61)
Tinder-like Swipe

Here parameter rotationAngle takes radians. You can give how much rotation you want here. In our case 0.61 is radians expression for 35°. Now we need one mathematical formula to change tilt angle with respect to distance. The distance here is, distanceMoved a parameter from our previous findings. There should be something for divisionParam here to work with respect to distanceMoved. The divisionParam here we are taking is calculated by this way. The total distance we have to move from the center/tilt angle.

The total distance overall we have to cover is half of screen width. It’s nothing but (self.view.frame.size/2). We have to cover this distance with a tilt angle of 0.61(in degrees 35°). You can change this angle to anything you want. Now the formula becomes,

divisionParam = (Total distance to be covered/tilt angle) = (self.view.frame.size/2)/0.61

Define this divisionParam globally. So that we will use anywhere. Now the rotation angle for CGATransform will become

rotationAngle = (The distance we moved from original position/divisionParam)

The same we discussed above will look like this in coding format:

cardView.transform = CGAffineTransform(rotationAngle: distanceMoved/divisionParam)
Tinder-like Swipe

Now rotation angle changs with respect to distance. That’s cool. Now after releasing the card it has to come back to its original form. Right now, you can observe it’s not happening. It’s coming with the same tilt we applied on it. We have very handy parameter from CGAffineTransform for this purpose.

Add this code:

cardView.transform = .identity 
Tinder-like Swipe

Below where we made our card position to be reset to center in step 2.

5. Other customizations:

If you are feeling that, to load card every time running application is cumbersome, you can put some button to reset. Just add the button by drag & drop and use the same chunk of code we use to get the card back to its original position. So the reset method will look like this.

func resetCardViewToOriginalPosition(){  
    cardView.center = self.view.center  
    self.sadImageView.alpha = 0  
    self.smileImageView.alpha = 0  
    cardView.transform = .identity  
} 
Tinder-like Swipe

We can do lot’s of customizations here. You can change card layout as per your requirement. You can change tilt of card while swiping. You can scale the card as it’s dragging. What not, almost everything you can customize. You can find whole source code from here.

Conclusion

Tinder app is extracting whole power of UIKit framework. Tinder app UI is completely trendsetting UI. One of the feature that got famous from this app UI is swipeable deck of cards. Users loved it. There are many libraries out there on the internet to make this kind of UI job easier. One of those libraries is Koloda. Which got very good attention from many developers. Another library is MDCSwipeToChoose. If you don’t want to struggle a lot, to make things easier and faster go for any of those libraries.

Are you looking for Android as well? Check it out here: Tinder like Swipe Slider for Android.

Sivajee Battina
I'm an iOS developer with the capability of working on multiple projects at a time. Hunting for bugs and killing them with programming sword is my habit for the most of the time. Love to help, share and learn knowledge through leading platforms like StackOverflow. If 100% bug-free software is impossible, I love to dare that impossibility.