Giter Site home page Giter Site logo

alikaragoz / mcswipetableviewcell Goto Github PK

View Code? Open in Web Editor NEW
3.0K 146.0 411.0 1.58 MB

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

License: MIT License

Objective-C 98.82% Ruby 1.18%

mcswipetableviewcell's Introduction

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 () <MCSwipeTableViewCellDelegate>
#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:

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.

mcswipetableviewcell's People

Contributors

alikaragoz avatar bryant1410 avatar djsison avatar gpoitch avatar joeblau avatar jschmid avatar mtnbarreto avatar tomatrow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mcswipetableviewcell's Issues

Use Text Instead of Icon?

something like:

[cell setFirstStateName:@"justOpened"
                     firstColor:[UIColor colorWithRed:85.0/255.0 green:213.0/255.0 blue:80.0/255.0 alpha:1.0]

version 1.2.0 not found in pod

Hi Alikaragoz,

i got this error when i pod install

[!] Required version (MCSwipeTableViewCell (~> 1.2.0)) not found for MCSwipeTableViewCell.
Available versions: 1.1.1, 1.1.0, 1.0.1, 1.0.0

Delete entire Section

Do we have any option to delete entire section,
and section is having two row
I mean to say, when we swipe any row in the section, the entire section has to move and show delete button.
Thanks

Static Lib

It's possible to have a static lib of MCSwipeTableViewCell?

(Concurrency) completionBlock executes on main thread

From NSOperation Class Reference:
The exact execution context for your completion block is not guaranteed but is typically a secondary thread.

However, MCSwipeTableViewCell runs completionBlock on the main thread which might cause confusion.

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

Hard to work with when using dynamic resources

First of all: Absolutely great work on the library.

I've got some food for thought for you and if desired, I can submit a pull request as I've already done most of the heavy lifting.

In order to get this library working, I had to rewrite certain portions of the codebase to use UIImages instead of NSStrings with the names of the respective resources.

I believe this is a significant flaw in the architecture for one simple reason:
If one uses dynamically generated resources (drawn at runtime) to achieve resolution independence instead of static bitmaps from the application bundle, ... you're well - screwed.

Now it's kind of impossible to use this library with code generated UIImages, well because I cannot address them by using a NSString.

Cheers

Configuring all the actions in one direction

First of all congratulations for building this library.

I'm actually trying to configure four actions on the left to right slide action.

While I'd like to request your assistance to point out where I can make adjustments for this to happen, I was considering that it may be nice to have this kind of flexibility available in the library.

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?

ReorderControl

It seems that MCSwipeTableViewCells are not able to use the default reordering controls?

I cant access them with cell.showsReorderControl.

Cells reappearing in UITableView after deletion

I'm scratching my head at this one. When I go to swipe and delete a cell, it'd reappear at certain intervals inside my UITableView. Any hints would be GREAT.

When I swipe enough cells, enough intervals are filled and the entire UITableView is just blanked. Please take a look at some of these images for explanation.

Here's how I'm handling deletion:

[cell setSwipeGestureWithView:checkView color:greenColor mode:MCSwipeTableViewCellModeExit state:MCSwipeTableViewCellState3 completionBlock:^(MCSwipeTableViewCell *_cell, MCSwipeTableViewCellState state, MCSwipeTableViewCellMode mode) {

    NSLog(@"Did swipe \"Cross\" cell");
    [self.tableView beginUpdates];
    NSMutableArray * mutableClone = [self.messages mutableCopy];
    NSIndexPath * index = [self.tableView indexPathForCell:_cell];
    [mutableClone removeObjectAtIndex:index.row];
    self.messages = mutableClone;
    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:index]
                          withRowAnimation:UITableViewRowAnimationFade];
    [self.tableView endUpdates];
}];

I can see that in my log that my messages array is getting de-incremented correctly when the tableview reloads...

Log

First swipe...
First swipe

When scrolling down...
First swipe

After swiping a lot
First swipe

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

The tableviewcell appears behind the moving cell when doing the swipe gesture

Hi to all, If you are having this problem, know that you need to add this to the ViewDidLoad Method to make it work, like this.

  • (void)viewDidLoad {
    [super viewDidLoad];

    UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
    [backgroundView setBackgroundColor:
    [UIColor colorWithRed:227.0 / 255.0 green:227.0 / 255.0 blue:227.0 / 255.0 alpha:1.0]];
    [self.tableView setBackgroundView:backgroundView];
    }

Cell with AVPlayer in it

Hello, I have been trying to use MCSwipeTableViewCell with a cell that has an AVPlayer in it. The cell works fine until I try swiping the cell. When I swipe, the item in the AVPlayer (video) disappears until the cell is returned to its original position. Thanks!

White background flickering

I don't know that's due to my tableview cell setup or not. If I cancel the swipe before achieving any mode, there's white background flickering, as this picture.

ios simulator screen shot sep 24 2013 1 56 47 pm

I can fix it by changing this line on bounceToOrigin method:

[_colorIndicatorView setBackgroundColor:[UIColor clearColor]];

to:

 [_colorIndicatorView setBackgroundColor:self.defaultColor]; //by Andri

Any thought?

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

Cell content's copy doesn't work

It seems that the gesture recognizer implemented in MCSwipeTableViewCell somehow overrides the one in the original UITableViewCell and therefore it is impossible to copy the cell's content with a long press gesture, this gesture is no longer recognized.

With this code it seems to work. Note I'm not sure if it has any unexpected drawbacks, nor if it is judicious to call the parent method here. Anyway here is the snippet:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
  if (gestureRecognizer == _panGestureRecognizer) {
    // ...
  }
  return [super gestureRecognizerShouldBegin:gestureRecognizer];
}

Too much padding for the third icon?

Have any of you guys encounter this problem in iOS7? There seems to be way too much padding to the icon. I also double check the icon, there's no empty space in the png.

untitled

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?

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. ๐Ÿ‘

minor bug

in offsetWithPercentage:
else if (offset > width) offset = 1.0;
i think should be ... offset = width.

though this line of code seems to never execute

null Image Error

When you swipe on IOS7 GM, you get this error for every tick event on the swipe.

[57324:a0b] CUICatalog: Invalid asset name supplied: (null), or invalid scale factor: 2.000000

I think the problem is here. Why is slideImageWithPercentage being called when the image is null?

    // Image Position
    if (imageName != nil) {
        [_slidingImageView setImage:[UIImage imageNamed:imageName]];
        [_slidingImageView setAlpha:[self imageAlphaWithPercentage:percentage]];
    }

    [self slideImageWithPercentage:percentage imageName:imageName isDragging:self.shouldAnimatesIcons];

Environment: Version 5.0 (5A1412) // iOS Simulator Version 7.0 (463.9.4)

UIPanGestureRecognizer cancel touches

I don't know if it's only me, but I had to add

[_panGestureRecognizer setCancelsTouchesInView:NO];

in - (void)initializer in order for my tableview cell to be able to detect selection.
Is this expected behaviour?

Disable multi swipe gesture

Hello, can't find option to disable multi swipe, can you explain how can I do it? I want to swipe only one cell and not many when I use multitouch on screen.

isBackgroundClear behavior

Is there any performance (or other) reason why this piece of code:

BOOL isContentViewBackgroundClear = !self.contentView.backgroundColor;
    if (isContentViewBackgroundClear) {
        BOOL isBackgroundClear = [self.backgroundColor isEqual:[UIColor clearColor]];
        self.contentView.backgroundColor = isBackgroundClear ? [UIColor whiteColor] :self.backgroundColor;
    }

assigns [UIColor whiteColor] instead of [UIColor clearColor] to self.contentView.backgroundColor?

A current project of mine uses transparent contentViews and UIImageViews on the background, so coloring the cell ends up breaking the UI.

If there are no known issues with using clearColor, may I suggest this modification?

AutoLayout

First of all, great work! Any ideas on how to use it with AutoLayout?

Crashes when repeatedly swiping to delete a cell

Try repeatedly swiping to delete a cell. If you do it fast enough before the delete animation finishes, it crashes... Any ideas how to fix this?

Here is the log:

2013-08-31 22:56:05.098 MCSwipe Demo[10639:907] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]'
*** First throw call stack:

handlePanGestureRecognizer - executeCompletionBlock EXC_BAD_ACCESS

I'm getting a EXC_BAD_ACCESS after I successfully finish swiping a table view cell.

In this part of the code:

if (cellState == MCSwipeTableViewCellState1 && _modeForState1) {
cellMode = self.modeForState1;
}

    else if (cellState == MCSwipeTableViewCellState2 && _modeForState2) {
        cellMode = self.modeForState2;
    }

    else if (cellState == MCSwipeTableViewCellState3 && _modeForState3) {
        cellMode = self.modeForState3;
    }

    else if (cellState == MCSwipeTableViewCellState4 && _modeForState4) {
        cellMode = self.modeForState4;
    }

    if (cellMode == MCSwipeTableViewCellModeExit && _direction != MCSwipeTableViewCellDirectionCenter) {
        [self moveWithDuration:animationDuration andDirection:_direction];
    }

    else {
        [self swipeToOriginWithCompletion:^{
            [self executeCompletionBlock];
        }];
    }

I crash on the [self executeCompletionBlock].

Swift Example

Anyone have an example using this code with Swift? I've been attempting to use it, but it's been throwing some errors with setSwipeGestureWithView.

Delegate method called two times

Hi, I'm trying to use your MCSwipeTableViewCell in my project and came across this problem:
When detecting the end of the swipe for the mode 'EXIT', before deleting the row I need to ask the user if he's sure about it.
So in the delegate method swipeTableViewCell: didEndSwipingWithState I only present an AlertView to the user. To keep track of the swiped cell index, I'm using this code:

NSIndexPath *selectedIndexPath = [self.tableView indexPathForCell: cell];
NSLog(@"%d", selectedIndexPath.row);

Now when logging that value, during a cell swiping, I get two results, the first one is the correct one, the other is the next cell.

Could you help me please?

Thanks.

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.

Updating the cell

Does anybody know how I could I update the cell subviews at end of swipe?

-(void)swipeTableViewCellDidEndSwiping:(MCSwipeTableViewCell *)cell {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}

Right now accessoryType does not attach to the horizontal slide view, and the same goes for textLabel, detailTextLabel...

Right swipe only - still left swipeable

Minor small bug here.

If you pull the "right swipe only" left, it indeed will not go.

However if you swipe it right a pixel or 5, then swipe left it will indeed go left.

iOS 8 - iPhone 5

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?

_colorIndicatorView backgroundColor crash

I'm using the method from the example:

  • (UIView *)viewWithImageName:(NSString *)imageName {
    UIImage *image = [UIImage imageNamed:imageName];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    imageView.contentMode = UIViewContentModeCenter;
    return imageView;
    }

After that when I run everything with the correct settings in cellForRowAtIndexPath, I get the following crash in animateWithOffset:

// Color
UIColor *color = [self colorWithPercentage:percentage];
if (color != nil) {
_colorIndicatorView.backgroundColor = color;
}

It seems that color isn't nil, but it's not returning a valid color so I get an EXC_BAD_ACCESS

This is what I have in my cellForRowAtIndexPath similar to the demo:

UIView *replyView = [self viewWithImageName:@"reply.png"];
UIColor *replyColor = [UIColor colorWithRed:0.0/255.0f green:235.0/255.0f blue:176.0/255.0f alpha:1.0];

If i change replyColor to something like [UIColor redColor] it doesn't crash...

Allow multiple states when setting swipe gesture

For convenience, it would be nice if I could use the same parameters with multiple states, instead of duplicating the block for each state:

For example:

MCSwipeTableViewCellState1|MCSwipeTableViewCellState3

To delete the cell when swiping left, or right.

[cell setSwipeGestureWithView:nil color:[UIColor redColor] mode:MCSwipeTableViewCellModeExit state:MCSwipeTableViewCellState1|MCSwipeTableViewCellState3 completionBlock:^(MCSwipeTableViewCell *cell, MCSwipeTableViewCellState state, MCSwipeTableViewCellMode mode) {
        // cell deletion code
}];

Thank you, and great work!

When swipe the label in the cell with xib it's offset of some pixel

Hello, i have problem with your amazing project, i have a uitableviewcell xib with a uilabel in it, and a subclass of it, here the the snippet:

#import <UIKit/UIKit.h>
#import "MCSwipeTableViewCell.h"

@interface ListViewCell : MCSwipeTableViewCell

@property (weak, nonatomic) IBOutlet UILabel *listName;
@property (weak, nonatomic) IBOutlet UIImageView *selectImg;

@end

and then in the .m file there is nothing, then i use your project in this way:

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

ListViewCell *cell = (ListViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
      NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"ListViewCell_iPhone" owner:self options:nil];
        cell = [nib objectAtIndex:0];
}

[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:0.0]
        secondStateIconName:nil
                secondColor:nil
              thirdIconName:@"cross.png"
                 thirdColor:[UIColor colorWithRed:232.0/255.0 green:61.0/255.0 blue:14.0/255.0 alpha:0.0]
             fourthIconName:nil
                fourthColor:nil];

cell.listName.text = [[self.list objectAtIndex:indexPath.row] name];

[cell setMode:MCSwipeTableViewCellModeSwitch];

return cell;
}

now, the problem is this, when i swipe on the cell, and i release it, the label in cell it's offset on the left of some pixel, then, when i click on the row it return at the normal position, how i can solve this problem?

Artifacts with accessoryView in cell

Hi Ali,
First of all thanks for this great cell view:)

I have ugly artifacts when trying to set accessoryView for cell.
It would be great to have supporting it.

Accessory View

Tableview error and app crash

Hi, I'm trying to implement the sliding cell but when I slide the cell to delete it i get this error:

2013-03-18 21:31:58.971 Demo[33684:c07] IndexPath : <NSIndexPath 0xc13b7e0> 2 indexes [0, 0] - MCSwipeTableViewCellState : 2 - MCSwipeTableViewCellMode : 0
2013-03-18 21:31:58.972 Demo[33684:c07] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2380.17/UITableView.m:1070
2013-03-18 21:31:58.972 Demo[33684:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), 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).'

How can I fix it?
Help! :)

Here is my code:

import "RecordingsViewController.h"

import <AVFoundation/AVFoundation.h>

import "MCSwipeTableViewCell.h"

@interface RecordingsViewController ()<AVAudioPlayerDelegate, MCSwipeTableViewCellDelegate> {
NSArray *_recordings;
NSInteger _currentRecording;
NSString *_documentsPath;

AVAudioPlayer *_audioPlayer;

}
@Property(nonatomic, assign) NSUInteger nbItems;

  • (void)playButtonTapped;

@EnD

@implementation RecordingsViewController

@synthesize tableview = _tableview;
@synthesize bgImageView = _bgImageView;
@synthesize playButton = _playButton;
@synthesize statusLabel = _statusLabel;
@synthesize titleLabel = _titleLabel;

  • (id)initWithRecordings:(NSArray *)recordings {
    self = [super initWithNibName:@"RecordingsView" bundle:nil];
    if (self) {
    self.title = @"Recordings";

    _recordings = recordings;
    _currentRecording = -1;
    
    _nbItems = _recordings;
    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    _documentsPath = [paths objectAtIndex:0];
    

    }

    return self;
    }

  • (void)viewDidLoad {
    [super viewDidLoad];

    if([[UIScreen mainScreen] scale] >= 2.0 && [[UIScreen mainScreen] bounds].size.height > 480) {
    [_bgImageView setImage:[UIImage imageNamed:@"[email protected]"]];
    }

    [self navigationController].navigationBar.backgroundColor = [UIColor clearColor];
    self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
    self.navigationController.navigationBar.translucent = YES;
    self.navigationController.navigationBar.opaque = NO;
    self.navigationController.navigationBar.tintColor = [UIColor clearColor];
    self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];

    [_playButton addTarget:self action:@selector(playButtonTapped) forControlEvents:UIControlEventTouchUpInside];
    [_statusLabel setText:@""];
    [_titleLabel setText:@""];
    }

  • (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    if(_audioPlayer && _audioPlayer.isPlaying) {
    [_audioPlayer stop];
    }
    }

  • (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    }

pragma mark -

pragma mark UITableViewDataSource/UITableViewDelegate Methods

  • (int)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
    }

  • (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [_recordings count];
    return _nbItems;

}

  • (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];
    }

    // For the delegate callback
    [cell setDelegate:self];

    // We need to provide the icon names and the desired colors
    [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];

    int row = indexPath.row;

    [[cell textLabel] setText:[_recordings objectAtIndex:row]];
    if(row == _currentRecording) {
    [cell setAccessoryView:[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"now_playing.png"]]];
    } else {
    [cell setAccessoryView:nil];
    }

    cell.textLabel.textColor = [UIColor whiteColor];
    cell.textLabel.shadowColor = [UIColor blackColor];

    return cell;
    }

  • (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 80.0;
    }

  • (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    if(indexPath.row == _currentRecording) {
    return;
    }

    if(_audioPlayer) {
    _audioPlayer.delegate = nil;
    [_audioPlayer stop];
    _audioPlayer = nil;
    }

    [_statusLabel setText:@""];

    _currentRecording = indexPath.row;
    NSString *filename = [_recordings objectAtIndex:indexPath.row];
    [_titleLabel setText:filename];

    NSString *path = [_documentsPath stringByAppendingPathComponent:filename];
    NSURL *url = [NSURL fileURLWithPath:path];
    NSError *error;
    _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    if(error) {
    [_statusLabel setText:[NSString stringWithFormat:@"%@", error.localizedDescription]];
    } else {
    if(_audioPlayer) {
    NSString *duration = [NSString stringWithFormat:@"%d:%02d", (int)_audioPlayer.duration / 60, (int)_audioPlayer.duration % 60];
    [_statusLabel setText:duration];
    [_playButton setImage:[UIImage imageNamed:@"pause.png"] forState:UIControlStateNormal];

        [_audioPlayer setDelegate:self];
        [_audioPlayer setVolume:0.5];
        [_audioPlayer prepareToPlay];
        [_audioPlayer play];
    }
    

    }

    [self.tableview reloadData];
    }

pragma mark - MCSwipeTableViewCellDelegate

  • (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) {
    _nbItems--;
    [self.tableview deleteRowsAtIndexPaths:@[[self.tableview indexPathForCell:cell]] withRowAnimation:UITableViewRowAnimationFade];
    }
    }

  • (void)reload:(id)sender {
    _nbItems++;
    [self.tableview reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
    }

pragma mark -

pragma mark AVAudioPlayerDelegate Methods

  • (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
    [_playButton setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];
    }
  • (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error {
    [_statusLabel setText:[NSString stringWithFormat:@"%@", error.localizedDescription]];
    [_playButton setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];
    }

pragma mark -

pragma mark Private Methods

  • (void)playButtonTapped {
    if(_audioPlayer == nil) {
    return;
    }

    if(_audioPlayer.isPlaying) {
    [_audioPlayer pause];
    [_playButton setImage:[UIImage imageNamed:@"play.png"] forState:UIControlStateNormal];
    } else {
    [_audioPlayer play];
    [_playButton setImage:[UIImage imageNamed:@"pause.png"] forState:UIControlStateNormal];
    }
    }

@EnD

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.