2

I'm experiencing some weird behavior when trying to delete a row in a UITableView.

I have two tableviews in my app, and they both have practically the same code on the tableView:commitEditingStyle:forRowAtIndexPath: method. One is working fine, the other one has this issue: let's suppose I have more than, I don't know, X rows on my table view, so the cell reuse and scroll are both enabled. If I delete a row on the top of the list, the cells that are showing up on the bottom of the screen are being all duplicated by the bottom cell prior hitting the delete button. So if I delete 5 rows, for example, I'll have identical cells on my tableview. Then if I scroll the tableview they will all go back to normal. (or if I change viewcontroller and then go back to the tableview's one)

Here is the code of the working tableview:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
    if (search.text.length == 0) {
        [tableArray removeObjectAtIndex:indexPath.row];
        [goalTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [self setBG];
        tempArray = [NSArray arrayWithArray:tableArray];
        [[NSUserDefaults standardUserDefaults]setObject:tempArray forKey:@"currentArray"];
        totalGoals = [[NSUserDefaults standardUserDefaults] integerForKey:@"totalGoals"];
        totalGoals = totalGoals - 1;
        [[NSUserDefaults standardUserDefaults] setInteger:totalGoals forKey:@"totalGoals"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    } } }

And here is the code of the defective tableview:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
    if (search.text.length == 0) {
        [tableArray removeObjectAtIndex:indexPath.row];
        [goalTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [self setBG];
        tempArray = [NSArray arrayWithArray:tableArray];
        [[NSUserDefaults standardUserDefaults]setObject:tempArray forKey:@"completedArray"];
        completedGoals = [[NSUserDefaults standardUserDefaults] integerForKey:@"completedGoals"];
        completedGoals = completedGoals - 1;
        [[NSUserDefaults standardUserDefaults] setInteger:completedGoals forKey:@"completedGoals"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    } } }

Well, it's pretty much the same, so I'm a little lost here - They have the same code and one is working fine and the other isn't. Could it be an issue at the cellForRowAtIndexPath: method? I'm wondering that, but couldn't find nothing on this method, plus they are practically the same too.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString * identifier = @"Cell";
    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (cell==nil) { 
        //here I'm setting up the cells, labels, and stuff.
    }

    if (search.text.length == 0 && [filteredArray count] == 0) {
        NSDictionary * dict = [tableArray objectAtIndex:[tableArray count] - 1 - indexPath.row];
        //here I use the values on the dict to do some stuff with labels, etc.
    }
    return cell;
}

The thing is, I'm "fliping" the array with this line:

NSDictionary * dict = [tableArray objectAtIndex:[tableArray count] - 1 - indexPath.row];

If I don't do that, ie, when I do something like [tableArray objectAtIndex:indexPath.row] only, the deleting issue won't happen at all! It's something that happens cause of the reversed array. Oh, just to mention, when I'm populating the cell (when the view is loading, for example), the cell reuse is working just fine, no duplicate cells or anything like that. It's something that only happens when deleting rows.

Unihedron
  • 10,902
  • 13
  • 62
  • 72
user2743901
  • 33
  • 1
  • 6

1 Answers1

0

Check your cellforRowAtIndexPath: for both tables. There should be some difference in the way you are reusing your cells.

In iOS6 and further you need not check if(cell == nil) as I have done below

static NSString *CellIdentifier = @"Cell";    
CustomCell *cell = (CustomCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

Other thing that you can do is try reloading you table after deleting. Hope this solves your problem

Ganesh Somani
  • 2,280
  • 2
  • 28
  • 37
  • Well, honestly I've been looking for something in cellForRow... and couldn't find anything, it's been a day doing that already! Plus, the fact that when I randomly scroll the table up and down the cells go back to the way they should be doesn't mean this method is fine? I mean, the method is called everytime I scroll the table and when I do that it just set the cells right! Or am I guessing wrong here? – user2743901 Feb 05 '14 at 21:44
  • Okay, I found the problem but don't know how to fix it. Here's the thing, that table is reversed! Some way this messes up the deleting system. I've tried reversing it in two ways: first by populating the tableview with array count - 1 - indexpath.row, and the second by using the reverseObjectEnumerator method. They seem to be equivalent! No matter what method I use to reverse the tableview, I still get this problem. If I don't reverse the tableview, the deleting system works perfectly. Any ideas? Thank you! – user2743901 Feb 05 '14 at 22:40
  • I didn't get you there! What do you mean by table being reversed. Can you share your `cellforRowAtIndexPath:` code – Ganesh Somani Feb 06 '14 at 09:55
  • My datasource is an array, and I'm not displaying the rows on the same order of the array.. in other words, new cells show up at the top, not at the bottom! I'll add the code on the OP. – user2743901 Feb 06 '14 at 17:27
  • Please check through your `cellForRowAtIndexPath:`. I believe that you are initialising a cell but your are not assigning it data you want, hence you are getting a duplicate cell. Probably some wrong condition checking somewhere. – Ganesh Somani Feb 10 '14 at 09:50