Yalantis: iOS, Android And Web App Development Company

How We Built Tinder-Like Koloda Animation in Swift

Sometimes I think that Tinder’s mission in this world isn’t as much about helping people meet each other as it is about setting up new design trends. Then, we can definitely say that Tinder has already accomplished its mission, and can rest in peace until a new Tinder appears.

Tinder’s swipe right to like and left to pass isn’t only popular among dating app developers. Shopping apps, like Fancy, are following suit with similar swipe-to-like app formats. They are picking up this trend because quick card-based interactions really work. Items on a card grab users’ attention and urge them to take an action, thus increasing user engagement.

There are other examples of apps of various categories that use Tinder’s swipe theory: Jobr, an app for ... you guessed it – jobs and networking, real estate app Uptop, even Chrome for iOS which uses cards to manage bookmarks.

koloda animation

We featured card layouts and swipe-based navigation in our article about this year’s design trends. A bit later, our designer Dmitry Goncharov created an animation that follows Tinder’s trend, and he actually did it on purpose. The swipe-to-like interface is something people want to be part of.

We called our Tinder-style card-based animation Koloda which is a Ukrainian word for deck (of cards), and it sounds like fun to us. The component can be used in different local event apps, and even in Tinder if it adds a possibility to choose dating places. The concept created by Dmitriy was implemented by Eugene Andreyev, our iOS developer. Check it out on GitHub.

How we built Koloda animation

by Eugene Andreyev

Tinder’s swipe-to-like interface has been borrowed by various apps, so there are a few ready-made mobile libraries out there that an app developer can use. At first, I decided to look at MDCSwipeToChoose and TinderSimpleSwipeCards but as it turned out, these solutions weren’t perfect for my particular case.

I wanted the animation to be as simple and convenient as the data source driven views like UITableView. Therefore, I created a custom component for the animation. It consists of the three main parts:

  1. DraggableCardView – a card which displays content.
  2. OverlayView – a dynamic view which changes depending on where a user drags a card (to the left or to the right).
  3. KolodaView – a view that controls loading and interactions between cards.

Koloda Swipe to like tinder interface

DraggableCardView implementation

As I already mentioned, DraggableCardView is a card that displays content. There are many tutorials on the internet that explain how to animate cards in the Tinder style. I chose one of these solutions, looked at it, changed a few things, and here I am with my DraggableCardView implemented with the help of UIPanGestureRecognizer and CGAffineTransform. See the coding part below:

func panGestureRecognized(gestureRecognizer: UIPanGestureRecognizer) {
       xDistanceFromCenter = gestureRecognizer.translationInView(self).x
       yDistanceFromCenter = gestureRecognizer.translationInView(self).y

       let touchLocation = gestureRecognizer.locationInView(self)
       switch gestureRecognizer.state {
       case .Began:
           originalLocation = center

           animationDirection = touchLocation.y >= frame.size.height / 2 ? -1.0 : 1.0      
           layer.shouldRasterize = true

       case .Changed:

           let rotationStrength = min(xDistanceFromCenter! / self.frame.size.width, rotationMax)
           let rotationAngle = animationDirection! * defaultRotationAngle * rotationStrength
           let scaleStrength = 1 - ((1 - scaleMin) * fabs(rotationStrength))
           let scale = max(scaleStrength, scaleMin)
           layer.rasterizationScale = scale * UIScreen.mainScreen().scale
           let transform = CGAffineTransformMakeRotation(rotationAngle)
           let scaleTransform = CGAffineTransformScale(transform, scale, scale)

           self.transform = scaleTransform
           center = CGPoint(x: originalLocation!.x + xDistanceFromCenter!, y: originalLocation!.y + yDistanceFromCenter!)
           updateOverlayWithFinishPercent(xDistanceFromCenter! / frame.size.width)
           //100% - for proportion
           delegate?.cardDraggedWithFinishPercent(self, percent: min(fabs(xDistanceFromCenter! * 100 / frame.size.width), 100))
       case .Ended:
           layer.shouldRasterize = false
       default :

When a user starts dragging a top card, it’s turning and becoming shorter all the way until it reaches an action margin (go or pass an event), and after that it moves away from the screen. The distance to the action margin is represented in percent (100%). While the top card is being dragged, the card below is reacting too – it’s either expanding or contracting. In other words, the animation of an upper and a lower card stops simultaneously.

The overlay gets updated with every move. It changes transparency in the process of animation ( 5% –  hardly seen, 100% – clearly seen).

In order to avoid a card’s edges becoming sharp during movement I used shouldRasterize layer option.

What’s more, I had to consider reset situation which happens once a card fails to reach the action margin (ending point) and comes back to the initial state. I used Facebook Pop framework for this situation, and also for the “undo” action. If you remember, this framework drives animations and transitions in Paper app. It supports dynamic bounce animations and allows to build realistic interactions based on physics with just a few lines of code.

OverlayView implementation

OverlayView is a view that is added on top of a card during animation. It has only one variable called overlayState with two options: when a user drags a card to the left, the overlayState adds a red hue to the card, and when a card is moved to the right, the variable uses the other option to make the UI become green.

To implement custom actions for the overlay, we should inherit from OverlayView, and reload the operation didSet in the overlayState:

public enum OverlayMode{
   case None
   case Left
   case Right

public class OverlayView: UIView {
      public var overlayState:OverlayMode = OverlayMode.None

class ExampleOverlayView: OverlayView {
override var overlayState:OverlayMode  {
       didSet {
           switch overlayState {
           case .Left :
               overlayImageView.image = UIImage(named: overlayLeftImageName)
           case .Right :
               overlayImageView.image = UIImage(named: overlayRightImageName)
               overlayImageView.image = nil




KolodaView implementation

The KolodaView class does card loading and card management job. You can either implement it in the code or in the Interface Builder. Then, you should specify a datasource and add a delegate (optional). After that, you should implement the following methods of the KolodaViewDataSource protocol in the datasource-class:

    func kolodaNumberOfCards(koloda: KolodaView) -> UInt
    func kolodaViewForCardAtIndex(koloda: KolodaView, index: UInt) -> UIView
    func kolodaViewForCardOverlayAtIndex(koloda: KolodaView, index: UInt) -> OverlayView?

Regarding the callbacks, we get them through the delegate’s methods.


Remember our story about developing the Guillotine menu animation for Android where Dmytro Denysenko, our Android developer, had to resort to high school Math course to build a custom interpolator? Geometry also helped me in my iOS development endeavours!

The most interesting thing in the Tinder-like animation is movement of lower cards while a user is dragging an upper card. I wanted to make the Koloda animation flexible, so that I could easily specify the number of cards I want to display on the screen. So I took a piece of paper and started my calculations.

How we develop Koloda Tinder-like card view animation

KolodaView had to display a correct number of cards below the top card, and make them occupy the right positions when the animation starts. To make it possible, I had to calculate frames for all the cards by adding the corresponding indexes to each element. For example, the first card has an [i] index, the second one would have a [i+1] index, the third – [i+2], and so on.

You can see the calculations of the original frame and the size of the first card below:

developing Tinder cardsAnd in the code:

private func frameForCardAtIndex(index: UInt) -> CGRect {
       let bottomOffset:CGFloat = 0
       let topOffset = backgroundCardsTopMargin * CGFloat(self.countOfVisibleCards - 1)
       let xOffset = backgroundCardsLeftMargin * CGFloat(index)
       let scalePercent = backgroundCardsScalePercent
       let width = CGRectGetWidth(self.frame) * pow(scalePercent, CGFloat(index))
       let height = (CGRectGetHeight(self.frame) - bottomOffset - topOffset) * pow(scalePercent, CGFloat(index))
       let multiplier: CGFloat = index > 0 ? 1.0 : 0.0
       let previousCardFrame = index > 0 ? frameForCardAtIndex(max(index - 1, 0)) : CGRectZero
       let yOffset = (CGRectGetHeight(previousCardFrame) - height + previousCardFrame.origin.y + backgroundCardsTopMargin) * multiplier
       let frame = CGRect(x: xOffset, y: yOffset, width: width, height: height)     

       return frame

Now, since we know the indexes, card frames, and also a percent at which the animation ends (from the DraggableCardView), we can easily find out where the cards below will go once an upper card is swiped. After than we can implement PercentDrivenAnimation.

As a result, I achieved an easy to use component with an interesting name Koloda. Any developer can customize it by setting their content and overlay. In the future, I’d like to make it possible to customize frames’ calculations and animations so that any developer can make their own unique component.

Read also our article Koloda Tinder-like animation Version 2 where we improved funcationality of existing animation.

Check out KolodaView animaton on GitHub

See also:  Boboarding: open source onboarding constructor




Tinder Swipes

Our open source component that improves Tinder-like swipe-right-to-like-left-to-pass animation

How We Built Tinder-Like Koloda Animation in Swift
Written by Eugene Andreyev

How We Built Tinder-Like Koloda Animation in Swift

Sometimes I think that Tinder’s mission in this world isn’t as much about helping people meet each other ...

Koloda Tinder-Like Animation Version 2. Prototyping in Pixate and Development in Swift
Written by Eugene Andreyev and Dmitriy Goncharov

Koloda Tinder-Like Animation Version 2. Prototyping in Pixate and Development in Swift

About a month ago we told you about how we developed Tinder-like Koloda in Swift. The animation proved ...

Force Awakens

Our creative UI concept that features Star Wars. We implemented the animations for iOS and Android

UIDynamics, UIKit or OpenGL? 3 Types of iOS Animations for the Star Wars
Written by Artem Sydorenko and Kostya Trundayev

UIDynamics, UIKit or OpenGL? 3 Types of iOS Animations for the Star Wars

Have you ever thought that George Lucas’s epic space opera can, in fact, be implemented on iOS? We got ...

Star Wars: The Force Awakens Or How to Crumble View Into Tiny Pieces on Android
Written by Artem Kholodnyi

Star Wars: The Force Awakens Or How to Crumble View Into Tiny Pieces on Android

We released our epic Star Wars animation for iOS last month, and you probably had no doubt that we were...

iOS animation designs

Rethinking menu, tab bar, pull-to-refresh, and other navigation elements in iPhone apps

How We Created Tab Bar Animation for iOS
Written by Kate Abrosimova, Igor Muzyka, and Vitaly Rubtsov

How We Created Tab Bar Animation for iOS

Today’s smartphones are becoming more like tablets, or there is even a better word – phablets. Big scre...

How We Created Guillotine Menu Animation for iOS
Written by Maksym Lazebnyi and Vitaly Rubtsov

How We Created Guillotine Menu Animation for iOS

Have you ever wondered why a sidebar in apps has to be a “side” bar? Why not to make it a “topbar,” or ...

How We Developed ColorMatchTabs Animation for iOS
Written by Sergey Butenko and Sergii Ganushchak

How We Developed ColorMatchTabs Animation for iOS

The article talks about a UI animation for a concept of a review app that we developed for iPhones.

How We Built Pull To Make Soup Animation
Written by Anastasiya Gorban

How We Built Pull To Make Soup Animation

Pull-to-refresh is a great place for creativity! But we’re building cool pull-to-refresh animations not...

Creating ForceBlur Animation for iOS Messaging Apps
Written by Alexey Chernish, Kostya Trundayev, and Sergey Butenko

Creating ForceBlur Animation for iOS Messaging Apps

ForceBlur iOS animation is based on force touch feature that can be used for sensitive content.

Excited to create something outstanding?

We share the same interests.

Let's team up!