Convenient UITableViewCell subclass that implements a swippable content to trigger actions (similar to the Mailbox app).

Overview

MCSwipeTableViewCell

An effort to show how one would implement a UITableViewCell like the one we can see in the very well executed Mailbox iOS app.

Preview

Exit Mode

The exit mode MCSwipeTableViewCellModeExit is the original behavior we can see in the Mailbox app. Swiping the cell should make it disappear. Convenient in destructive modes.

Switch Mode

The switch mode MCSwipeTableViewCellModeSwitch is a new behavior I'm introducing. The cell will bounce back after selecting a state, this allows you to keep the cell. Convenient to switch an option quickly.

API Reference

Please refer to the header file MCSwipeTableViewCell.h for a complete overview of the capabilities of the class.

Usage

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    MCSwipeTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (!cell) {
        cell = [[MCSwipeTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];

        // Remove inset of iOS 7 separators.
        if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
            cell.separatorInset = UIEdgeInsetsZero;
        }

        [cell setSelectionStyle:UITableViewCellSelectionStyleGray];

        // Setting the background color of the cell.
        cell.contentView.backgroundColor = [UIColor whiteColor];
    }

    // Configuring the views and colors.
    UIView *checkView = [self viewWithImageName:@"check"];
    UIColor *greenColor = [UIColor colorWithRed:85.0 / 255.0 green:213.0 / 255.0 blue:80.0 / 255.0 alpha:1.0];

    UIView *crossView = [self viewWithImageName:@"cross"];
    UIColor *redColor = [UIColor colorWithRed:232.0 / 255.0 green:61.0 / 255.0 blue:14.0 / 255.0 alpha:1.0];

    UIView *clockView = [self viewWithImageName:@"clock"];
    UIColor *yellowColor = [UIColor colorWithRed:254.0 / 255.0 green:217.0 / 255.0 blue:56.0 / 255.0 alpha:1.0];

    UIView *listView = [self viewWithImageName:@"list"];
    UIColor *brownColor = [UIColor colorWithRed:206.0 / 255.0 green:149.0 / 255.0 blue:98.0 / 255.0 alpha:1.0];

    // Setting the default inactive state color to the tableView background color.
    [cell setDefaultColor:self.tableView.backgroundView.backgroundColor];

    [cell.textLabel setText:@"Switch Mode Cell"];
    [cell.detailTextLabel setText:@"Swipe to switch"];

    // Adding gestures per state basis.
    [cell setSwipeGestureWithView:checkView color:greenColor mode:MCSwipeTableViewCellModeSwitch state:MCSwipeTableViewCellState1 completionBlock:^(MCSwipeTableViewCell *cell, MCSwipeTableViewCellState state, MCSwipeTableViewCellMode mode) {
        NSLog(@"Did swipe \"Checkmark\" cell");
    }];

    [cell setSwipeGestureWithView:crossView color:redColor mode:MCSwipeTableViewCellModeSwitch state:MCSwipeTableViewCellState2 completionBlock:^(MCSwipeTableViewCell *cell, MCSwipeTableViewCellState state, MCSwipeTableViewCellMode mode) {
        NSLog(@"Did swipe \"Cross\" cell");
    }];

    [cell setSwipeGestureWithView:clockView color:yellowColor mode:MCSwipeTableViewCellModeSwitch state:MCSwipeTableViewCellState3 completionBlock:^(MCSwipeTableViewCell *cell, MCSwipeTableViewCellState state, MCSwipeTableViewCellMode mode) {
        NSLog(@"Did swipe \"Clock\" cell");
    }];

    [cell setSwipeGestureWithView:listView color:brownColor mode:MCSwipeTableViewCellModeSwitch state:MCSwipeTableViewCellState4 completionBlock:^(MCSwipeTableViewCell *cell, MCSwipeTableViewCellState state, MCSwipeTableViewCellMode mode) {
        NSLog(@"Did swipe \"List\" cell");
    }];

    return cell;
}

Delegate

MCSwipeTableViewCell has a set of delegate methods in order to track the user behaviors. Take a look at the header file to be aware of all the methods provided by MCSwipeTableViewCellDelegate.

@interface MCTableViewController () 
#pragma mark - MCSwipeTableViewCellDelegate

// Called when the user starts swiping the cell.
- (void)swipeTableViewCellDidStartSwiping:(MCSwipeTableViewCell *)cell;

// Called when the user ends swiping the cell.
- (void)swipeTableViewCellDidEndSwiping:(MCSwipeTableViewCell *)cell;

// Called during a swipe.
- (void)swipeTableViewCell:(MCSwipeTableViewCell *)cell didSwipeWithPercentage:(CGFloat)percentage;

Cell Deletion

In MCSwipeTableViewCellModeExit mode you may want to delete the cell with a nice fading animation, the following lines will give you an idea how to execute it:

[cell setSwipeGestureWithView:crossView color:redColor mode:MCSwipeTableViewCellModeExit state:MCSwipeTableViewCellState2 completionBlock:^(MCSwipeTableViewCell *cell, MCSwipeTableViewCellState state, MCSwipeTableViewCellMode mode) {
    NSLog(@"Did swipe \"Cross\" cell");

    // Code to delete your cell...

}];

You can also ask for a confirmation before deleting a cell:

__weak MCTableViewController *weakSelf = self;

[cell setSwipeGestureWithView:crossView color:redColor mode:MCSwipeTableViewCellModeExit state:MCSwipeTableViewCellState1 completionBlock:^(MCSwipeTableViewCell *cell, MCSwipeTableViewCellState state, MCSwipeTableViewCellMode mode) {
    NSLog(@"Did swipe \"Cross\" cell");

    __strong MCTableViewController *strongSelf = weakSelf;
    strongSelf.cellToDelete = cell;

    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Delete?"
                                                        message:@"Are you sure your want to delete the cell?"
                                                       delegate:self
                                              cancelButtonTitle:@"No"
                                              otherButtonTitles:@"Yes", nil];
    [alertView show];
}];

Then handle the UIAlertView action:

#pragma mark - UIAlertViewDelegate

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {

    // No
    if (buttonIndex == 0) {
        [_cellToDelete swipeToOriginWithCompletion:^{
            NSLog(@"Swiped back");
        }];
        _cellToDelete = nil;
    }

    // Yes
    else {
        // Code to delete your cell...
    }
}

There is also an example in the demo project, I recommend to take a look at it.

Changing the trigger percentage

If the default trigger limits do not fit to your needs you can change them with the firstTrigger (default: 25%) and secondTrigger (Default: 75%) properties.

cell.firstTrigger = 0.1;
cell.secondTrigger = 0.5;

Reseting cell position

It is possible to put the cell back to it's position when using the MCSwipeTableViewCellModeExit mode with the -swipeToOriginWithCompletion: method:

[cell swipeToOriginWithCompletion:^{
    NSLog(@"Cell swiped back!");
}];

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects.

$ gem install cocoapods

To integrate MCSwipeTableViewCell into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'MCSwipeTableViewCell', '~> 2.1.4'

Then, run the following command:

$ pod install

Carthage

Carthage is a decentralized dependency manager that automates the process of adding frameworks to your Cocoa application.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate MCSwipeTableViewCell into your Xcode project using Carthage, specify it in your Cartfile:

= 2.1.4">
github "alikaragoz/MCSwipeTableViewCell" >= 2.1.4

Compatibility

This library is not compatible with auto-layout so you will need to disable auto-layout in your xib properties.

Requirements

  • iOS >= 5.0
  • ARC

Contact

Ali Karagoz

License

MCSwipeTableViewCell is available under the MIT license. See the LICENSE file for more info.

Comments
  • View hierarchy broken in iOS 7

    View hierarchy broken in iOS 7

    The colorIndicatorView is for some reason over the contentView of the cell. Changing the insertion to [self insertSubview:_colorIndicatorView atIndex:0]; fixes the problem and makes this iOS 7 compatible.

    opened by chrisalbert 9
  • I think it's cancelling UITapGestureRecognizer inside my cell subclass

    I think it's cancelling UITapGestureRecognizer inside my cell subclass

    Just looking to eliminate this from debugging, would it be a possibility that the library is conflicting with existing Gesture Recognizers I have set up inside my cell?

    opened by benhowdle89 7
  • Not working with Custom Cells

    Not working with Custom Cells

    So far, your repository is awesome. But I'm not able to use it with custom UITableViewCells containing Labels, Views etc.

    Is it my fault or isn't it working with custom cells?

    enhancement 
    opened by hartlco 7
  • Crash when selecting quickly after swiping

    Crash when selecting quickly after swiping

    To replicate this, swipe and very quickly tap on the same cell or another cell.

    This will result in a crash because selection and swiping leads to different segue. Does anyone have any idea how to fix this?

    opened by auto234875 5
  • Not able to disable cell swipe control to the right

    Not able to disable cell swipe control to the right

    I want to use the control for only swiping right to left and disable state1 and state2 from the left to the right. I have tried:

    [cell setModeForState1:MCSwipeTableViewCellModeNone];
    [cell setModeForState2:MCSwipeTableViewCellModeNone];
    [cell setModeForState3:MCSwipeTableViewCellModeSwitch];
    [cell setModeForState4:MCSwipeTableViewCellModeExit];
    

    but this does not disable the swipe from left to right on the cell. Is this even possible?

    opened by stevewirig 5
  • Help with 'Invalid update: invalid number of rows in section 0.' error

    Help with 'Invalid update: invalid number of rows in section 0.' error

    Getting this error after i try to delete the cell...

    Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (7) must be equal to the number of rows contained in that section before the update (7), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).

    Here all the code I have

    @interface ReceiptsViewController ()
    @property (nonatomic, strong) NSMutableArray *devices;
    
    @end
    
    @implementation ReceiptsViewController
    @synthesize tableView = _tableView;
    
    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSManagedObjectContext *context = [self managedObjectContext];
    
        if (editingStyle == UITableViewCellEditingStyleDelete) {
            // Delete object from database
            [context deleteObject:[self.devices objectAtIndex:indexPath.row]];
    
            NSError *error = nil;
            if (![context save:&error]) {
                NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]);
                return;
            }
    
    
            // Remove device from table view
    
            [KGStatusBar showErrorWithStatus:@"Receipt Removed"];
            [self.devices removeObjectAtIndex:indexPath.row];
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        }
    }
    
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return 1;
    }
    
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return _devices.count;
    
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
        MCSwipeTableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
        if (!cell){
            cell = [[MCSwipeTableViewCell alloc] initWithStyle:self reuseIdentifier:CellIdentifier];
        }
        [cell setDelegate:self];
        [cell setFirstStateIconName:@"check.png"
                         firstColor:[UIColor colorWithRed:85.0/255.0 green:213.0/255.0 blue:80.0/255.0 alpha:1.0]
                secondStateIconName:@"cross.png"
                        secondColor:[UIColor colorWithRed:232.0/255.0 green:61.0/255.0 blue:14.0/255.0 alpha:1.0]
                      thirdIconName:@"clock.png"
                         thirdColor:[UIColor colorWithRed:254.0/255.0 green:217.0/255.0 blue:56.0/255.0 alpha:1.0]
                     fourthIconName:@"list.png"
                        fourthColor:[UIColor colorWithRed:206.0/255.0 green:149.0/255.0 blue:98.0/255.0 alpha:1.0]];
    
        // We need to set a background to the content view of the cell
        [cell.contentView setBackgroundColor:[UIColor whiteColor]];
    
        // Setting the type of the cell
        [cell setMode:MCSwipeTableViewCellModeExit];
    
    
        NSManagedObject *device = [self.devices objectAtIndex:indexPath.row];
        [cell.self.name setText:[device valueForKey:@"name"]];
        [cell.self.company setText:[device valueForKey:@"company"]];
        [cell.self.price setText:[NSString stringWithFormat:@"$%@", [device valueForKey:@"price"]]];
        [cell setSelectionStyle:UITableViewCellSelectionStyleGray];
        cell.backgroundView = [[UIImageView alloc] initWithImage:[[UIImage imageNamed:@"TableViewCell.png"] stretchableImageWithLeftCapWidth:0.0 topCapHeight:5.0]];
    
        return cell;
    }
    
    
    - (void)swipeTableViewCell:(MCSwipeTableViewCell *)cell didTriggerState:(MCSwipeTableViewCellState)state withMode:(MCSwipeTableViewCellMode)mode {
        NSLog(@"IndexPath : %@ - MCSwipeTableViewCellState : %d - MCSwipeTableViewCellMode : %d", [self.tableView indexPathForCell:cell], state, mode);
    
        if (mode == MCSwipeTableViewCellModeExit) {
            [self.tableView deleteRowsAtIndexPaths:@[[self.tableView indexPathForCell:cell]] withRowAnimation:UITableViewRowAnimationFade];
        }
    }
    
    @end
    
    question 
    opened by KyleGreenlaw 5
  • Storyboard

    Storyboard

    Hey there

    I have a custom UITableViewCell that inherits from MCSwipeTableViewCell

    However swiping it doesn't work. It is also designed in storyboard

    Please tell me how to fix this bug

    opened by hoan 5
  • Cell doesn't fit after reload

    Cell doesn't fit after reload

    hi, i really love your swipeable table cell but i am having an issue... why after a reload data it doesn't fit to tableview revealing the last color of action performed?

    How can i fix this?

    Schermata 2013-03-26 alle 20 41 49

    opened by fabiosoft 5
  • Why fade out the sliding view on exit?

    Why fade out the sliding view on exit?

    Why is it necessary to fade out the sliding view on exit?

    [UIView animateWithDuration:duration delay:0 options:(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionAllowUserInteraction) animations:^{
        _contentScreenshotView.frame = frame;
        _slidingView.alpha = 0;
        [self slideViewWithPercentage:percentage view:_activeView isDragging:self.shouldAnimateIcons];
    } completion:^(BOOL finished) {
        [self executeCompletionBlock];
    }];
    

    I would like to show the sliding view for an instant before removing the cell, to display a confirmation text. Is there a way to do this without modifying the current code?

    Without this line I wouldn't have any issue.

    Thanks for making this class. It saved me a lot of time, and the code is very nice. :+1:

    opened by hpique 4
  • How to implement just one option in a particular swipe?

    How to implement just one option in a particular swipe?

    I have a question, for the right-left swipe I would like to implement only one option instead of two. How can I only implement one option in one direction and two options in the other?

    Concurrently, what if I just want one option in either directions?

    opened by fahadahmed 4
  • sectionIndexTitlesForTableView

    sectionIndexTitlesForTableView

    When I was using sectionIndex (alphabetical on the right side) the color underlying the cell is exposed. It's possible to get around this by adding another view (hack) to mask it but have I done something wrong or is this a known issue.

    If I've been unclear please let me know and I will elaborate.

    And thanks again for the great library.

    opened by mychrisdangelo 4
  • Add individual trigger limit properties

    Add individual trigger limit properties

    Add rightFirstTrigger, rightSecondTrigger, leftFirstTrigger and leftSecondTrigger properties to MCSwipeTableViewCell to make #81 "Different swipe percentages for left vs right" possible.

    This fix is backward compatible, and you can still use firstTrigger and secondTrigger properties.

    opened by kentaroi 0
  • Change renderInContext to drawViewHierarchyInRect  in imageWithView

    Change renderInContext to drawViewHierarchyInRect in imageWithView

    Change [view.layer renderInContext:UIGraphicsGetCurrentContext()];

    To: [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];

    It runs much faster. From my tests on my app it went from 0.625468s to 0.014225.

    Heres is a better explanation on possible choices and it has a link to why it is better: http://stackoverflow.com/questions/19066717/how-to-render-view-into-image-faster

    opened by frapsMatheus 0
  • Feature Request :- Multiple actionable buttons on swiping.

    Feature Request :- Multiple actionable buttons on swiping.

    It will be more awesome if we can have more than one action buttons on swiping. Eg. Instagram comment cell which on swipe provides multiple action buttons eg. "Reply", "Delete", "Report" etc.

    opened by kidsid49 0
Releases(2.1.4)
  • 2.1.4(Jul 18, 2015)

  • 2.1.3(Jul 14, 2015)

  • 2.1.2(Sep 21, 2014)

  • 2.1.0(Feb 2, 2014)

    • Added the ability to set multiple states when setting swipe gesture. This allows you to use the same configuration for several states. a59c36c64b8fc046fb90fd1a210a5b707ee9251c
    • Improved behaviour of the sliding view when the 1st and 2nd triggers have been changed. 50d22972d0e71d99f5b4250a25e0bbff133bcf26
    Source code(tar.gz)
    Source code(zip)
  • 2.0.0(Jan 16, 2014)

    • Gestures are now added per state basis via the -setSwipeGestureWithView:color:mode:state:completionBlock.
    • Added the ability the set a UIView in the state indicator instead of a UIImage via the image name which was not very convenient.
    • Support of accessory views and edition mode.
    • Spring based animations on iOS 7 and above.
    • Improved header documentation.
    • Bug fixes.
    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Jan 5, 2014)

    • Added the ability to change the triggers percentage.
    • Added the ability to disable left or right swipe.
    • Added a method to manually swipe back the cell to it's original position.
    • Added a delegate method to detect if the user swiped the cell but did not trigger any state.
    • Fixed a potential crash when provided image is nil.
    Source code(tar.gz)
    Source code(zip)
Owner
Ali Karagoz
Wizard @mojo_video_app. Created @suplco. Ex @gopro / @quik_app / @zenlyapp
Ali Karagoz
An easy to use UITableViewCell subclass that allows to display swippable buttons with a variety of transitions.

MGSwipeTableCell MGSwipeTableCell is an easy to use UITableViewCell subclass that allows to display swipeable buttons with a variety of transitions. T

Imanol Fernandez 7k Dec 26, 2022
Swipeable UITableViewCell/UICollectionViewCell based on the stock Mail.app, implemented in Swift.

SwipeCellKit Swipeable UITableViewCell/UICollectionViewCell based on the stock Mail.app, implemented in Swift. About A swipeable UITableViewCell or UI

null 6k Jan 7, 2023
Simple timeline view implemented by UITableViewCell

TimelineTableViewCell TimelineTableViewCell is a simple timeline view implemented by UITableViewCell. The UI design of TimelineTableViewCell is inspir

Zheng-Xiang Ke 1.3k Dec 25, 2022
A subclass of UITableView that styles it like Settings.app on iPad

TORoundedTableView As of iOS 13, Apple has released an official version of this table view style called UITableViewStyleInsetGrouped! Yay! In order to

Tim Oliver 162 Nov 2, 2022
UIViewController subclass inspired by "Inbox by google" animated transitioning.

SAInboxViewController SAInboxViewController realizes Inbox like view transitioning. You can launch sample project on web browser from here. Features I

Taiki Suzuki 298 Jun 29, 2022
This framework allows you to build Table views using UIKit with syntax similar to SwiftUI

This framework allows you to build Table views using UIKit with syntax similar to SwiftUI

Fun 60 Dec 17, 2022
INTUZ is presenting an interesting a Multilevel Expand/Collapse UITableView App Control to integrate inside your native iOS-based application

INTUZ is presenting an interesting a Multilevel Expand/Collapse UITableView App Control to integrate inside your native iOS-based application. MultilevelTableView is a simple component, which lets you use the tableview with multilevel tree view in your project.

INTUZ 3 Oct 3, 2022
ClassicPhotos is a TableView App demos how to optimize image download and filter with operation queue.

ClassicPhotos ClassicPhotos is a TableView App demos how to optimize image download and filter with operation queue. With Operation and Operation Queu

Kushal Shingote 2 Dec 18, 2021
An easy-to-use UITableViewCell subclass that implements a swippable content view which exposes utility buttons (similar to iOS 7 Mail Application)

SWTableViewCell An easy-to-use UITableViewCell subclass that implements a swipeable content view which exposes utility buttons (similar to iOS 7 Mail

Christopher Wendel 7.2k Dec 31, 2022
Easy to use UITableViewCell implementing swiping to trigger actions.

SwipyCell Swipeable UITableViewCell inspired by the popular Mailbox App, implemented in Swift. Preview Exit Mode The .exit mode is the original behavi

Moritz Sternemann 249 Dec 5, 2022
An easy to use UITableViewCell subclass that allows to display swippable buttons with a variety of transitions.

MGSwipeTableCell MGSwipeTableCell is an easy to use UITableViewCell subclass that allows to display swipeable buttons with a variety of transitions. T

Imanol Fernandez 7k Dec 26, 2022
NSFileProviderManager.signalEnumerator does not trigger update of UIDocumentBrowserViewController

FB9715717 Which area are you seeing an issue with? FileProvider Framework Incorrect/Unexpected Behavior Subject NSFileProviderManager.signalEnumerator

Marcin Krzyzanowski 2 Dec 11, 2021
TriggerSlider is a simple SwiftUI trigger slider

TriggerSlider is a simple SwiftUI trigger slider which can be used instead of a button, e.g. in a situation where the

Dominik Butz 4 Dec 16, 2022
ActionBee is a programmable pasteboard action trigger.

ActionBee ActionBee is a programmable pasteboard action trigger. Preview Video It can be used to clean your URL in text. To see code or import this mo

Derek Jones 2 Aug 24, 2022
A UICollectionViewLayout subclass displays its items as rows of items similar to the App Store Feature tab without a nested UITableView/UICollectionView hack.

CollectionViewShelfLayout A UICollectionViewLayout subclass displays its items as rows of items similar to the App Store Feature tab without a nested

Pitiphong Phongpattranont 374 Oct 22, 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
Swipeable UITableViewCell/UICollectionViewCell based on the stock Mail.app, implemented in Swift.

SwipeCellKit Swipeable UITableViewCell/UICollectionViewCell based on the stock Mail.app, implemented in Swift. About A swipeable UITableViewCell or UI

null 6k Jan 7, 2023
The app provides additional actions for the Shortcuts app on macOS and iOS.

Actions Supercharge your shortcuts The app provides additional actions for the Shortcuts app on macOS and iOS. Submit action idea (Submit an issue bef

Sindre Sorhus 1.2k Dec 29, 2022
Light wrapper of UITableViewCell that allows extra customization for tvOS

TvOSCustomizableTableViewCell Light wrapper of UITableViewCell that allows extra customization for tvOS If you would like to have the same level of cu

Zattoo 31 Nov 9, 2022