Swipe to "like" or "dislike" any view, just like Tinder.app. Build a flashcard app, a photo viewer, and more, in minutes, not hours!

Overview

MDCSwipeToChoose

Build Status

Swipe to "like" or "dislike" any view, just like Tinder.app. Build a flashcard app, a photo viewer, and more, in minutes, not hours!

  • Use UIView+MDCSwipeToChoose to add a swipe gesture and callbacks to any UIView.
  • Use MDCSwipeToChooseView to get a UI nearly identical to Tinder.app in just a few lines of code.

You may view slides on some the architecture decisions that went into this library here.

How to Install via CocoaPods

Place the following in your Podfile and run pod install:

pod "MDCSwipeToChoose"

How to Use

Check out the sample app for an example of how to use MDCSwipeToChooseView to build the UI in the GIF above.

NOTE: You must run pod install in the Examples/LikedOrNope directory before building the example app.

Every public class contains documentation in its header file.

Swiping Yes/No

The following is an example of how you can use MDCSwipeToChooseView to display a photo. The user can choose to delete it by swiping left, or save it by swiping right.

Objective-C

#import <MDCSwipeToChoose/MDCSwipeToChoose.h>

// ... in a view controller

#pragma mark - Creating and Customizing a MDCSwipeToChooseView

- (void)viewDidLoad {
    [super viewDidLoad];

    // You can customize MDCSwipeToChooseView using MDCSwipeToChooseViewOptions.
    MDCSwipeToChooseViewOptions *options = [MDCSwipeToChooseViewOptions new];
    options.likedText = @"Keep";
    options.likedColor = [UIColor blueColor];
    options.nopeText = @"Delete";
    options.onPan = ^(MDCPanState *state){
        if (state.thresholdRatio == 1.f && state.direction == MDCSwipeDirectionLeft) {
            NSLog(@"Let go now to delete the photo!");
        }
    };

    MDCSwipeToChooseView *view = [[MDCSwipeToChooseView alloc] initWithFrame:self.view.bounds
                                                                     options:options];
    view.imageView.image = [UIImage imageNamed:@"photo"];
    [self.view addSubview:view];
}

#pragma mark - MDCSwipeToChooseDelegate Callbacks

// This is called when a user didn't fully swipe left or right.
- (void)viewDidCancelSwipe:(UIView *)view {
    NSLog(@"Couldn't decide, huh?");
}

// Sent before a choice is made. Cancel the choice by returning `NO`. Otherwise return `YES`.
- (BOOL)view:(UIView *)view shouldBeChosenWithDirection:(MDCSwipeDirection)direction {
    if (direction == MDCSwipeDirectionLeft) {
        return YES;
    } else {
        // Snap the view back and cancel the choice.
        [UIView animateWithDuration:0.16 animations:^{
            view.transform = CGAffineTransformIdentity;
            view.center = [view superview].center;
        }];
        return NO;
    }
}

// This is called then a user swipes the view fully left or right.
- (void)view:(UIView *)view wasChosenWithDirection:(MDCSwipeDirection)direction {
    if (direction == MDCSwipeDirectionLeft) {
        NSLog(@"Photo deleted!");
    } else {
        NSLog(@"Photo saved!");
    }
}

Swift

To use objective-c code from swift, you need to use bridging-header.

#ifndef BridgingHeader_h
#define BridgingHeader_h

#import <UIKit/UIKit.h>
#import <MDCSwipeToChoose/MDCSwipeToChoose.h>

#endif

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

		let options = MDCSwipeToChooseViewOptions()
		options.delegate = self
		options.likedText = "Keep"
		options.likedColor = UIColor.blue
		options.nopeText = "Delete"
		options.nopeColor = UIColor.red
		options.onPan = { state -> Void in
			if state?.thresholdRatio == 1 && state?.direction == .left {
				print("Photo deleted!")
			}
		}

		let view = MDCSwipeToChooseView(frame: self.view.bounds, options: options)
		view?.imageView.image = UIImage(named: "photo.png")
		self.view.addSubview(view!)
	}

}

extension ViewController: MDCSwipeToChooseDelegate {

	// This is called when a user didn't fully swipe left or right.
	func viewDidCancelSwipe(_ view: UIView) -> Void{
		print("Couldn't decide, huh?")
	}

	// Sent before a choice is made. Cancel the choice by returning `false`. Otherwise return `true`.
	func view(_ view: UIView, shouldBeChosenWith: MDCSwipeDirection) -> Bool {
		if shouldBeChosenWith == .left {
			return true
		} else {
			// Snap the view back and cancel the choice.
			UIView.animate(withDuration: 0.16, animations: { () -> Void in
				view.transform = CGAffineTransform.identity
				view.center = view.superview!.center
			})
			return false
		}
	}

	// This is called when a user swipes the view fully left or right.
	func view(_ view: UIView, wasChosenWith: MDCSwipeDirection) -> Void {
		if wasChosenWith == .left {
			print("Photo deleted!")
		} else {
			print("Photo saved!")
		}
	}
}

If you're using CocoaPods 0.36+ (perhaps because you want to include pods that contain Swift code) and you've included the use_frameworks! directive in your Podfile, then you've converted all your pods (including MDCSwipeToChoose) into frameworks. Therefore, you'll need to include the line

import MDCSwipeToChoose

...in your Swift files (even if you're using a bridging header).

More Generic Swiping

You don't have to use a subclass of MDCChooseView. You can use the mdc_swipeToChooseSetup: method on any UIView to enable swipe-to-choose.

In the following example, we adjust the opacity of a UIWebView when it's panned left and right.

#import <MDCSwipeToChoose/MDCSwipeToChoose.h>

// ... in a view controller

- (void)viewDidLoad {
    [super viewDidLoad];

    MDCSwipeOptions *options = [MDCSwipeOptions new];
    options.delegate = self;
    options.onPan = ^(MDCPanState *state){
        switch (state.direction) {
            case MDCSwipeDirectionLeft:
                self.webView.alpha = 0.5f - state.thresholdRatio;
                break;
            case MDCSwipeDirectionRight:
                self.webView.alpha = 0.5f + state.thresholdRatio;
                break;
            case MDCSwipeDirectionNone:
                self.webView.alpha = 0.5f;
                break;
        }
    };
    [self.webView mdc_swipeToChooseSetup:options];
}

##Swiping in Swift

The following is an example of how you can use MDCSwipeToChooseView to display a photo in swift. The user can choose to delete it by swiping left, or save it by swiping right.

First you must create a BridgingHeader.h file

#ifndef ProjectName_BridgingHeader_h
#define ProjectName_BridgingHeader_h


#import <UIKit/UIKit.h>
#import <MDCSwipeToChoose/MDCSwipeToChoose.h>

#endif

You must then add the bridging header file to the project by navigating to Build Settings then searching for 'Bridging Header'. Double click the field and type: ProjectName/BridgingHeader.h as the value

// Creating and Customizing a MDCSwipeToChooseView

override func viewDidLoad(){
    super.viewDidLoad()

    // You can customize MDCSwipeToChooseView using MDCSwipeToChooseViewOptions.
    let options:MDCSwipeToChooseViewOptions = MDCSwipeToChooseViewOptions()
    options.delegate = self
    options.likedText = "Keep"
    options.likedColor = UIColor.blue
    options.nopeText = "Delete"
    options.nopeColor = UIColor.red
    options.onPan = { state -> Void in
    if (state?.thresholdRatio == 1.0 && state?.direction == .left) {
        print("Let go now to delete the photo!")
    }
}

let view:MDCSwipeToChooseView = MDCSwipeToChooseView(frame:self.view.bounds, options:options)
    view.imageView.image = UIImage(named:"photo")
    self.view.addSubview(view)
}

// MDCSwipeToChooseDelegate Callbacks

// This is called when a user didn't fully swipe left or right.
func viewDidCancelSwipe(_ view: UIView) -> Void {
    print("Couldn't decide, huh?")
}

// Sent before a choice is made. Cancel the choice by returning `false`. Otherwise return `true`.
func view(_ view:UIView, shouldBeChosenWith: MDCSwipeDirection) -> Bool {
    if (shouldBeChosenWith == .left) {
        return true
    } else {
        // Snap the view back and cancel the choice.
        UIView.animate(withDuration: 0.16, animations: { () -> Void in
            view.transform = CGAffineTransform.identity
            view.center = self.view.center
        })
    return false
    }
}

// This is called when a user swipes the view fully left or right.
func view(_ view: UIView, wasChosenWith: MDCSwipeDirection) -> Void{
    if (wasChosenWith == .left) {
        print("Photo deleted!")
    } else {
        print("Photo saved!")
    }
}

Swiping programmatically

As of version 0.2.0, you may also swipe a view programmatically:

Objective-C

self.swipeToChooseView(mdc_swipe:MDCSwipeDirection.Left)
[self.swipeToChooseView mdc_swipe:MDCSwipeDirectionLeft];

Swift

self.swipeToChooseView.mdc_swipe(.left)

Disable swiping gesture

You may also disable the swiping gesture and only allowed to swipe programmatically

Objective-C

MDCSwipeToChooseViewOptions *options = [MDCSwipeToChooseViewOptions new];
options.swipeEnabled = NO;

Swift

let options = MDCSwipeToChooseViewOptions()
options.swipeEnabled = false

License

All the source code is distributed under the MIT license. See the LICENSE file for details. The license does not apply to the images used in the sample apps.

Comments
  • LikeOrNope in swift

    LikeOrNope in swift

    I have implemented MDCSwipeToChoose into a swift project and have the view controller currently swiping, however I am having alot of trouble getting the graphics down and loading the stack as it is done in likeornope.. Is there any chance there is a swift version of likeornope available or will one be coming soon. I think I speak for many new IOS developers by saying this would be extremely useful.

    Thanks, Rich

    opened by rjburdish 7
  • pod install isn't working on LikedOrNope project

    pod install isn't working on LikedOrNope project

    After entering pod install in the LikedOrNope directory, I am getting this error.

    MacBook-Pro:LikedOrNope varungoel$ pod install Analyzing dependencies /Users/varungoel/.rvm/gems/ruby-2.0.0-p353@global/gems/cocoapods-0.33.1/lib/cocoapods/executable.rb:55: warning: Insecure world writable dir /usr/local/bin in PATH, mode 040777 [!] An error occurred while performing git pull on repo master. [!] /usr/bin/git pull --ff-only

    error: RPC failed; result=56, HTTP code = 200

    fatal: The remote end hung up unexpectedly

    fatal: early EOF

    fatal: index-pack failed

    Has anyone been able to install this pod successfully?

    opened by goelv 6
  • Animation for Liked and Nope button does not work

    Animation for Liked and Nope button does not work

    When user tap Liked or Nope button . The action works correctly except that the frontView is completely disappear without any animation . How can I solve this ? The example app works just fine .But when I use it on my project ,it does not work.

    opened by kong707 5
  • mdc_swipe Issue

    mdc_swipe Issue

    I'm running across an issue where programmatic swiping without panning first causes the view to always swipe left, regardless of the direction I choose. From there on, it swipes in the correct direction (no pan needed)

    Also if I initially pan before swiping, the first programmatic selection is correct the first time around.

    Anyone else experience this?

    opened by acegreen 4
  • Swift adoption.

    Swift adoption.

    Hey. I tried installing this component via pods to use it with Swift, but got an error which I cant figure out how to fix (as I know zero Objective-C). Maybe some1 could take a quick look ? Cheers in advance !

    I created a new new project. did pod init inside. added pod "MDCSwipeToChoose" to Podfile. ran pod install Opened the newly created workspace. created BridgingHeader.h file. Added #import <MDCSwipeToChoose/MDCSwipeToChoose.h> Added BridgingHeader.h path to apps target Swift Compiler - Code Generator section.

    And got an error inside MDCSwipeToChooseDelegate.h file: screen shot 2014-10-24 at 21 48 41 screen shot 2014-10-24 at 21 46 41 screen shot 2014-10-24 at 21 46 30

    opened by Katafalkas 4
  • Swiping A View Programmatically

    Swiping A View Programmatically

    Im trying to swipe a View Programmatically but [self.swipeToChooseView mdc_swipe:MDCSwipeDirectionLeft]; has not been working.Am i doing something wrong?

    opened by bk207004 4
  • Property 'superview' not found on object of type 'ViewController *'

    Property 'superview' not found on object of type 'ViewController *'

    I got this error message in this code

    - (BOOL)view:(UIView *)view shouldBeChosenWithDirection:(MDCSwipeDirection)direction {
        if (direction == MDCSwipeDirectionLeft) {
            return YES;
        } else {
            // Snap the view back and cancel the choice.
            [UIView animateWithDuration:0.16 animations:^{
                view.transform = CGAffineTransformIdentity;
                view.center = self.superview.center;
            }];
            return NO;
        }
    }
    
    opened by datomnurdin 3
  • Build failing?

    Build failing?

    Looks like the Travis CI build is failing: https://travis-ci.org/modocache/MDCSwipeToChoose/builds/54823755

    The error message is strange: Reason: The run destination iPad 2 is not valid for Testing the scheme 'MDCSwipeToChoose'.

    opened by modocache 3
  • Add social_media_url to the Podspec

    Add social_media_url to the Podspec

    You should add the social_media_url attribute to your podspec for extra internet win!

    It's relatively useful right now, but should be much more useful soon with feeds.cocoapods.org and the upcoming search changes :)

    opened by orta 3
  • Swiping fully in any direction destroys the view. Need an option to not destroy.

    Swiping fully in any direction destroys the view. Need an option to not destroy.

    When using someUIView.mdc_swipeToChooseSetup(...), a full swipe to the left or right will destroy the view.

    If this view was created with storybuilder, then an @IBAction or @IBoutlet links are gone, along with the entire view. For a lot of cases, that renders this library unusable :-(

    opened by benmathes 2
  • fatal error: unexpectedly found nil while unwrapping an Optional value

    fatal error: unexpectedly found nil while unwrapping an Optional value

    Running the Swift example: SwiftLikedOrNope I get the following error while:

    fatal error: unexpectedly found nil while unwrapping an Optional value
    

    The error is reported in class ChoosePersonView: MDCSwipeToChooseView Line 43

    self.imageView.image = self.person.Image!
    
    opened by confile 2
  • View stucked in position on when app goes to background

    View stucked in position on when app goes to background

    Hi everybody, first I want to thank you for great plugin. Will try to describe my problem. I have implemented your plugin and everything works as it should. But there's one bug occurring while you are already swiping View. If during swiping your app goes to background (for example: somebody calls you, or just for testing, hit home button during swipe), after returning to app View will stuck somewhere in process off swiping and now it's position is calculated as starting for next swiping. What is wrong. View should return to it's starting position before app went to background.

    I attached picture with "censored" content, but just look at cards. This is position they have after resuming app. mdc-bug

    Bye

    opened by matuskopo 2
  • Prevent the MDCSwipeToChooseView from being removed

    Prevent the MDCSwipeToChooseView from being removed

    Is there a way to prevent the MDCSwipeToChooseViews from being removed from their superview after a swipe? I would like to keep the views since the user can navigate backwards through the cards in my app.

    Thanks in advance!

    opened by adeeb1 1
  • Xcode : Error on building Example

    Xcode : Error on building Example

    Hi,

    First, let me thank you for this projet. Second, I've to admit that I'm a beginner in iOS dev, so please forgive me if I've forget something obvious.

    After set up my BridgingHeader.h file in my project, and declare it in the build settings, I got a compilation error :

    xcode

    Any idea ?

    opened by Think-It 4
Releases(v0.2.3)
Owner
Brian Gesiak
Brian Gesiak
A easy-to-use SwiftUI view for Tinder like cards on iOS, macOS & watchOS.

?? CardStack A easy-to-use SwiftUI view for Tinder like cards on iOS, macOS & watchOS. Installation Xcode 11 & Swift Package Manager Use the package r

Deniz Adalar 285 Jan 3, 2023
KolodaView is a class designed to simplify the implementation of Tinder like cards on iOS.

KolodaView Check this article on our blog. Purpose KolodaView is a class designed to simplify the implementation of Tinder like cards on iOS. It adds

Yalantis 5.2k Jan 2, 2023
🃏 Tinder like card interface

Features Swift 3 Custom views for the card & overlay Generic Dynamically add new cards on top or on the bottom Lazy view loading Setup pod 'DMSwipeCar

Dylan Marriott 250 Nov 15, 2022
A marriage between the Shazam Discover UI and Tinder, built with UICollectionView in Swift.

VerticalCardSwiper A marriage between the Shazam Discover UI and Tinder, built with UICollectionView in Swift. Project goal and information The goal o

Joni Van Roost 1.2k Dec 28, 2022
🔥 A multi-directional card swiping library inspired by Tinder

Made with ❤️ by Mac Gallagher Features ?? Advanced swipe recognition based on velocity and card position ?? Manual and programmatic actions ?? Smooth

Mac Gallagher 754 Dec 28, 2022
🃏 Cardslider is a design UI controller that allows you to swipe through cards with pictures and accompanying descriptions.

CARD SLIDER UI controller that allows you to swipe through cards with pictures. We specialize in the designing and coding of custom UI for Mobile Apps

Ramotion 1.2k Dec 19, 2022
Awesome looking Dial like card selection ViewController

KVCardSelectionVC Awesome looking Dial like card selection ViewController An updated Swift 3 working version of : https://github.com/atljeremy/JFCardS

Kunal Verma 23 Feb 1, 2021
A navigation controller that displays its view controllers as an interactive stack of cards.

CardNavigation The easiest way to turn a navigation controller into an interactive stack of cards. Highlights ✅ Fully interactive and interruptible ✅

James Randolph 41 Sep 29, 2022
A SwiftUI card view, made great for setup interactions.

SlideOverCard A SwiftUI card design, similar to the one used by Apple in HomeKit, AirPods, Apple Card and AirTag setup, NFC scanning, Wi-Fi password s

João Gabriel 716 Dec 29, 2022
Card-based view controller for apps that display content cards with accompanying maps, similar to Apple Maps.

TripGo Card View Controller This is a repo for providing the card-based design for TripGo as well as the TripKitUI SDK by SkedGo. Specs 1. Basic funct

SkedGo 6 Oct 15, 2022
SimpleCardView-SwiftUI is a very simple card view written with SwiftUI

SimpleCardView-SwiftUI is a very simple card view written with SwiftUI

Tomortec 3 May 19, 2022
A SwiftUI view that arranges its children in a whimsical interactive deck of cards, as seen in Big News

CardStack A SwiftUI view that arranges its children in a whimsical interactive deck of cards. CardStack mimics the behaviour of the photo stack in iMe

The Not So Big Company 74 Dec 13, 2022
This UI attempts to capture the Quibi Card Stack and the associated User Interaction.

RGStack This UI attempts to capture the Quibi Card Stack and the associated User Interaction. Required A View that conforms to the ConfigurableCard pr

RGeleta 96 Dec 18, 2022
DTPhotoViewerController - A fully customizable photo viewer ViewController to display single photo or collection of photos, inspired by Facebook photo viewer.

DTPhotoViewerController Example Demo video: https://youtu.be/aTLx4M4zsKk DTPhotoViewerController is very simple to use, if you want to display only on

Tung Vo 277 Dec 17, 2022
Work-hours-mac - Simple app that tracks your work hours from the status bar

Track Your Work Hours Simple app that tracks your work hours from status bar. Fe

Niteo 44 Dec 2, 2022
Photo Browser / Viewer inspired by Facebook's and Tweetbot's with ARC support, swipe-to-dismiss, image progress and more

IDMPhotoBrowser IDMPhotoBrowser is a new implementation based on MWPhotoBrowser. We've added both user experience and technical features inspired by F

Thiago Peres 2.7k Dec 21, 2022
Swipe able, customizable card stack view, Tinder like card stack view based on UICollectionView. Cards UI

Swipable, customizable card stack view, Tinder like card stack view based on UICollectionView. Cards UI Сocoapods installation Add in your Podfile: po

Indy 850 Nov 17, 2022
Alejandro Piguave 24 Dec 30, 2022
Jogendra 113 Nov 28, 2022
Create a beautiful Onabording for your iOS/iPadOS apps in just a few minutes.

Create a beautiful Onabording for your iOS/iPadOS apps in just a few minutes.

Jem Alvarez 6 Sep 9, 2022