Brosef
Brosef

Reputation: 3095

Multiple cell deletion from core data tableview deleting wrong row

I have a UITableView that is listed in descending order and each tableview cell is associated with a file. The data for the tableview is from a NSFetchResultsController. I've enabled multiple row deleting but the deleting execution doesn't seem to be programmed correctly. If I only have 5 rows, the fifth row will be at the top with an index 0 and a file title "track5". Row 4 will have a file "track4" and an index 1 and so on all the way down to row 1 with a file "track1" and an index of 4. I also have an NSLog that outputs the index of each row being deleted and the associated file.

When deleting, if I select rows 4,3, and 2 out of the 5 rows, I end up deleting 4, 3, and 1.
My NSLog first shows index 1 and track4 being deleted, next index 2 and track 3 being deleted, then index 3 and track1 instead of track2. I'm assuming this is happening because the rows are being deleted one by one and the index of each remaining row is changing because of the prior cells being deleted. If I select rows 2, 3, and 4 in that order, everything will delete perfectly. Its only when i'm deleting in descending order. Whats the best way to fix this?

-(void) newMultiDelete
{
    NSArray *selectedRows = [self.audioTable indexPathsForSelectedRows];

    BOOL deleteSpecificRows = selectedRows.count > 0;
    if (deleteSpecificRows)
    {
        for (NSIndexPath *selectionIndex in selectedRows)
        {
            Recording * recording = [self.fetchCon objectAtIndexPath:selectionIndex];
            NSString * pathOfLastTrack = [self.managedDocument pathOfLastTrack];

            NSLog(@"Index path %li and title %@", (long)selectionIndex.row, recording.audioURL);
            [self.managedDocument.managedObjectContext deleteObject:recording];
            NSURL * audioURL = [[NSURL alloc] initWithString:recording.audioURL];
            [self.managedDocument removeFile:audioURL];

         }
    }

    [self.managedDocument.managedObjectContext save:nil];
    [self.managedDocument updateSaveContext];
    [self.audioTable reloadData];
}

Upvotes: 0

Views: 305

Answers (1)

pbasdf
pbasdf

Reputation: 21536

Build an array holding the objects to delete, before doing any deletions:

-(void) newMultiDelete
{
    NSArray *selectedRows = [self.audioTable indexPathsForSelectedRows];

    BOOL deleteSpecificRows = selectedRows.count > 0;
    if (deleteSpecificRows)
    {
        NSMutableArray *objectsToDelete = [NSMutableArray array];
        for (NSIndexPath *selectionIndex in selectedRows)
        {
            Recording * recording = [self.fetchCon objectAtIndexPath:selectionIndex];
            [objectsToDelete addObject:recording];
            NSLog(@"Index path %li and title %@", (long)selectionIndex.row, recording.audioURL);
        }
        for (Recording *recording in objectsToDelete)
        {
            NSString * pathOfLastTrack = [self.managedDocument pathOfLastTrack];
            NSURL * audioURL = [[NSURL alloc] initWithString:recording.audioURL];
            [self.managedDocument removeFile:audioURL];
            [self.managedDocument.managedObjectContext deleteObject:recording];
        }
    }
    [self.managedDocument.managedObjectContext save:nil];
    [self.managedDocument updateSaveContext];
    [self.audioTable reloadData];
}

Thus the deletions will not foul up the indexPaths for the other selected rows.

Upvotes: 1

Related Questions