Desmond
Desmond

Reputation: 5011

custom uitableviewcell content not animated when hiding delete button

I want to know what I am missing as my cell does not animate when hiding the delete button. The label jumps back to the original position before the delete button finish animating.

When I tap the round editing view to show the delete button, the label animation works:

Screenshot of cells where the delete button appears

However when I tap it again to hide the delete button, the movement of the label is not animated:

Screenshot of cells where the delete button disappears

Note: These screenshot are not created from the following code. But they show the problem.

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    homeCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[homeCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }

    // Set up the cell
    Consumed *drinkObj = [self.appDelegate.consumedDrinksArray objectAtIndex:indexPath.row];        
    cell.titleLabel.text = drinkObj.drinkName;
    NSString *detailTextTime = [NSDate stringFromDate:drinkObj.dateConsumed withFormat:@"h:mma"];

    NSString *detailTextrelative = [relativeDateTransformer transformedValue:drinkObj.dateConsumed];

    NSString *detailText =  [NSString stringWithFormat:@"%@ %@ ", detailTextTime,detailTextrelative];
    cell.timeLabel.text = detailText;

    cell.stdDLabel.text = @"999.0"; //[NSString stringWithFormat:@"%@", drinkObj.standardDrinks];
    cell.stdDLabel.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
    cell.titleLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
    cell.timeLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin;
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    return cell;
}

Upvotes: 13

Views: 2257

Answers (4)

LombaX
LombaX

Reputation: 17364

EDIT: I see that the bug is different from what I understood in first instance. Let's correct my answer. If I'm right, your delete button disappears correctly with an animation, but the content view resizes itself without animating (going behind the button animating).

It this case you have to manage the animation yourself. I give you the code assuming you are not supporting rotation. If you want to support rotation, you'll need more code :-)

Here is a sample project (there is a lot of code because I used the standard master-detail xcode template, look only at the custom cell): Sample Project

To apply it to your code:

First thing, change the autoresizing mask of the labels on the right side of the cell to anchor on the LEFT side.

I'm not sure if the right label is stdDLabel, I'll assume it

// if the right margin is flexible, the left-top-bottom are fixed
cell.stdDLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;

In your cell subclass override the setEditing:animated: method like this:

-(void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    // this is an array of the labels / view that you want to animate
    NSArray *objectsToMove = @[self.stdDLabel];
    // this is the amount of pixel to move - the width of the delete button
    float pixelToMove = 70.0f;

    float animationDuration = 0.3f;

    // calculating the delta. If set editing, move from right to left. otherwise, from left to right
    float delta = (editing) ? -pixelToMove : pixelToMove;

    // put the move code in a block for avoid repeating code in the if
    void (^moveBlock)() = ^{
        for (UIView *view in objectsToMove) {
            view.center = CGPointMake(view.center.x + delta, view.center.y);
        }
    };

    // we want to move the labels only if editing is different from the current isEditing state
    if (editing != self.isEditing)
    {
        // execute the move block, animated or not
        if (animated)
            [UIView animateWithDuration:animationDuration animations:moveBlock];
        else
            moveBlock();
    }

    // call the super implementation
    [super setEditing:editing animated:animated];
}

Upvotes: 7

Gaurav Rastogi
Gaurav Rastogi

Reputation: 2145

in the tableView:didEndEditingRowAtIndexPath: peform the task of re-locating the UILabels manually by settign their frames

- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    homeCell *cell = (homeCell *)[tableView cellForRowAtIndexpath:indexPath];

    UILabel *labelToBeRelocated = (UILabel *)[cell viewWithTag:YOUR_LABEL_TAG];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.25f];

    [labelToBeRelocated setFrame:CGRectMake(New_PosX , New_PosY , width , height)];

    [UIView commitAnimations];
}

Since the above delegate method is called after the EditingButton (Delete Button) is hidden in the UITableViewCell , hence the UILabel will be re-locating its position only after the delete button will be hidden . Hope it will help you.

Upvotes: 2

Divyam shukla
Divyam shukla

Reputation: 2046

You can perform this task using gesturerecognizer. It may help you to manage your cell.and also add a custome delete button on cell instead of default delete button.

Upvotes: 3

danh
danh

Reputation: 62676

I didn't check all of your code, but for sure you'll need to add begin/end updates on each side of the delete...

[self.drinksTableView beginUpdates];
[self.drinksTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.drinksTableView endUpdates];

...to get the animation.

Upvotes: 3

Related Questions