Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableViewCell delete button not disappearing

I'm using a UISegmentedControl to switch a UITableView between two datasets (think favorites and recents). Tapping the segmented control reloads the tableview with the different data set.

[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:anim];

When the user swipes to delete a row it works fine. HOWEVER when the user switches datasets via the segmented control, the DELETED CELL gets re-used without altering it's appearance (i.e. the red 'DELETE' button is still there and the row content is nowhere to be seen). This appears to be the opposite problem that most people are seeing which is the delete button not appearing.

This is the delete code:

- (UITableViewCellEditingStyle) tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellEditingStyleDelete;
}

- (void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        if ([self.current isEqualTo:self.favorites])
        {
            Favorite *fav = self.favorites[indexPath.row];

            NSMutableArray *mut = [self.favorites mutableCopy];
            [mut removeObjectAtIndex:indexPath.row];
            self.favorites = mut;
            self.current = self.favorites;
            [self.tableView deleteRowsAtIndexPaths:@[indexPath]
                                  withRowAnimation:UITableViewRowAnimationAutomatic];
        }
    }

}

The tableview is set to single select, and self.tableView.editing == NO. I have also tried using [self.tableView reloadData] and deleting/inserting the difference in rows from one dataset to the next. Neither works.

The UITableViewCell I'm using supplies no backgroundView or selectedBackgroundView


[EDIT]

Segmented Control Value Changed:

- (IBAction)modeChanged:(id)sender
{
    if (self.listMode.selectedSegmentIndex == 1)
    {
         self.current = self.favorites;
    }
    else 
    {
        self.current = self.recents;
    }
    // Tryin this:
    [self.tableView reloadData];
    // Tried this:
    // [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
}

// Only 1 Section per table
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
    return [self.current count];
}
like image 210
Stephen Furlani Avatar asked Nov 30 '13 20:11

Stephen Furlani


2 Answers

Oh for the love of...

I wasn't calling [super prepareForReuse]; in my UITableViewCell subclass.

UGH.

like image 188
Stephen Furlani Avatar answered Oct 21 '22 18:10

Stephen Furlani


I ran into the same thing: to "delete" a custom UITableViewCell, I was removing it from the table and putting it onto another list, which the user could then display in a modal view when they have regrets and want to put it back. In iOS7 (but not iOS6), the cells so moved had the big ugly "DELETE" button still on them, despite calling setEditing:NO and so on. (And in addition, the rest of the cell content was not drawn at all, even though inspecting the cells in the debugger showed that all the subpanes were still there.)

Unlike Stephen above, I hadn't overridden prepareForReuse, so that wasn't the problem. But it was related: in my case, the cells weren't created with a reuse identifier:

self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];

And per the docs, "If the cell object does not have an associated reuse identifier, this method is not called." But apparently, in iOS7 at least, it should be.

So the solution, in my case, was to explicitly call this [cell prepareForReuse] on each cell as I loaded it into the new table.

like image 25
Joe Strout Avatar answered Oct 21 '22 18:10

Joe Strout