在调用`deleteRowsAtIndexPaths:withRowAnimation`之前仍然生成删除对象:无效更新:第0部分中的行数无效

时间:2017-09-29 23:47:16

标签: ios objective-c uitableview

据我所知,此错误已多次发布。

问题是用户在调用deleteRowsAtIndexPaths:withRowAnimation之前忽略了从数据数组中删除对象。或者有时,他们同时调用reloadDatadeleteRowsAtIndexPaths:withRowAnimation

但是,在调用NSFetchedResultsController之前,我会从数据源(deleteRowsAtIndexPaths:withRowAnimation)中删除该对象。我不打电话给reloadData

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    /*Only allow deletion for collection table */
    if(_segmentedControl.selectedSegmentIndex == 1) {
        NSLog(@"delete ca");
        if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        CollectedLeaf* collectedLeaf = [collectionFetchedResultsController objectAtIndexPath:indexPath];
        LeafletPhotoUploader * leafletPhotoUploader = [[LeafletPhotoUploader alloc] init];
        leafletPhotoUploader.collectedLeaf = collectedLeaf;

        if([LeafletUserRegistration isUserRegistered]) {
            [leafletPhotoUploader deleteCollectedLeaf:collectedLeaf delegate:self];
        }


        // Delete the managed object for the given index path
        NSManagedObjectContext *context = [collectionFetchedResultsController managedObjectContext];
        [context deleteObject:[collectionFetchedResultsController objectAtIndexPath:indexPath]];

        // Save the context.
        NSError *error;
        if (![context save:&error])
        {
            NSLog(@"Failed to save to data store: %@", [error localizedDescription]);
            NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
            if(detailedErrors != nil && [detailedErrors count] > 0)
            {
                for(NSError* detailedError in detailedErrors)
                {
                    NSLog(@"  DetailedError: %@", [detailedError userInfo]);
                }
            }
            else 
            {
                NSLog(@"  %@", [error userInfo]);
            }
        }

    [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    }

    }

}

然而我仍然得到这个错误:

  

无效更新:第0部分中的行数无效   更新(2)后必须包含在现有部分中的行   等于之前该部分中包含的行数   update(2),加上或减去插入或删除的行数   该部分(0插入,1删除)和加号或减号的数量   移入或移出该部分的行(0移入,0移出)。

我尝试拨打reloadData而不是deleteRowsAtIndexPaths:withRowAnimation

enter image description here

虽然它解决了错误,但表单单元格并没有真正删除,你可以通过“Collected:null”标签看到它: enter image description here

此viewcontroller具有分段控件,其索引会更改加载到表中的数据。数据从NSFetchedResultsController

加载
if(_segmentedControl.selectedSegmentIndex == 1) {
       /// [_table removeFromSuperview];
        _search_bar.hidden=YES;

        UIImage *btnImage2 = [UIImage imageNamed:seg2_buttonImg];
        [_left_button setImage:btnImage2 forState:UIControlStateNormal];
        NSError *error;
        [self.collectionFetchedResultsController performFetch:&error];
        [self collectionFetchedResultsController];
        collectedLeafArray = [collectionFetchedResultsController fetchedObjects];
        [_table reloadData];
    }

因此,这是我对numberOfRowsInSection的实现:

- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    if(_segmentedControl.selectedSegmentIndex == 0){
        id <NSFetchedResultsSectionInfo> sectionInfo = [[speciesFetchedResultsController sections] objectAtIndex:section];

        return [sectionInfo numberOfObjects];
    }
    id <NSFetchedResultsSectionInfo> sectionInfo = [[collectionFetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
}

修改 如何在删除行后更新collectionFetchedResultsController的计数?

1 个答案:

答案 0 :(得分:0)

I found a solution here。基本上我是在数据源有时间完成删除之前调用deleteRowsAtIndexPaths:withRowAnimation

对于其他人在努力应对UITableView的变化时,这里有一个处理它的委托方法和here is the Apple documentation it was taken from

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {

    UITableView *tableView = self.tableView;

    switch(type) {

        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                   withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                   withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath]
                atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                   withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                   withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}