在canEditRowAtIndexPath方法中,UITableView的reloadData无法正常工作?

时间:2013-08-23 04:39:44

标签: iphone ios objective-c uitableview

在我的应用程序中,我从TableView中删除行后重新加载我的TableView [tablView reloadData];,然后canEditRowAtIndexPath方法总是要求(pervious)总行数。

例如:

如果我的TableView上有 5 行,那么我会从tableView中删除 1 行。删除后,我重新加载我的TableView [tablView reloadData]canEditRowAtIndexPath方法调用 5次而不是 4次 ??

所以我总是得到以下错误:

  

由于未捕获的异常'NSRangeException'终止应用,原因:' * ** - [__ NSArrayM objectAtIndex:]:索引5超出边界[0 .. 4]'

我也尝试在延迟一段时间后重新加载表格(使用NSTimer),但它也不适用于我。

我在这里放了一些代码:

我将canEditRowAtIndexPath应用于@"status" isEqualToString:@"directory"之类的特定行,

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"%d", self.listOfSounds.count);
    // Return NO if you do not want the specified item to be editable.
    if([[[self.listOfSounds objectAtIndex:indexPath.row] objectForKey:@"status"] isEqualToString:@"directory"])
        return YES;
    else
        return NO;
}  

删除行代码:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{

    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        [self.sql_ deleteSoundFileAudioTableWhereMainID:[[self.listOfSounds objectAtIndex:indexPath.row] objectForKey:@"main_id"]]; /// delete record from DB
        [self.listOfSounds removeObjectAtIndex:indexPath.row]; /// delete record from Array
        [self updateListofSoundsFile]; /// Custom method
    }
}

- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    return NO; // i also tried to  return YES;
}

此处updateListofSoundsFile是我的自定义方法代码:

-(void)updateListofSoundsFile
{
    if(self.listOfSounds.count > 0)
        [self.listOfSounds removeAllObjects];

    self.listOfSounds = [self.sql_ getAllDataFromAudioTable]; // get all record from DB
    NSLog(@"%d",self.listOfSounds.count);

    [self.tblView reloadData];  
}

请提出任何建议,我该如何解决这个问题? 谢谢:))

5 个答案:

答案 0 :(得分:5)

你需要从tableview中删除raw也可以从数组中删除项目并使用此行重新加载数据因为从数组中删除项目而不是tableview。

[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{

    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        [self.sql_ deleteSoundFileAudioTableWhereMainID:[[self.listOfSounds objectAtIndex:indexPath.row] objectForKey:@"main_id"]]; /// delete record from DB

        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [self.listOfSounds removeObjectAtIndex:indexPath.row]; /// delete record from Array

        [self updateListofSoundsFile]; /// Custom method
    }
}

答案 1 :(得分:2)

我遇到了同样的问题。问题是我删除了单元格的对象但是当我使用reloadData的{​​{1}}方法时,我的tableView方法没有被调用,因此能够编辑我的单元格不想编辑。真正的修复方法不是调用canEditRowAtIndexPath方法,而是调用deleteRowsAtIndexPaths方法。

基本上就是这里发生的事情:

当我致电[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];时: Nitin说,原始数据没有从reloadData中删除。因此,这不是解决方案。

当我致电tableView时: iOS检测到基础数据和单元格数量之间存在差异(因为我已经删除了基础对象)。结果是崩溃,这也不是解决方案(显然)。

现在进行修复!

当我致电deleteRowsAtIndexPaths时: 这导致tableView简单地重新加载该单个单元格并且它删除了原始数据。这是解决方案。

不是删除reloadRowsAtIndexPaths对象,而是尝试删除此时基本上没有任何内容支持的单元格(导致崩溃),只需删除dataSource对象,然后重新加载dataSource对象。 indexPath

的{1}}

以下是该方法的一般格式:

tableView

这是我第一次遇到残留原始数据的问题,而这些原始数据并未通过简单地调用- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { [myDataSourceArray removeObjectAtIndex:indexPath.row]; [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; } } 方法来删除。这当然是迄今为止我见过的最优雅的解决方案。

快乐的编码!我希望这会有所帮助。

答案 2 :(得分:0)

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{

    if (editingStyle == UITableViewCellEditingStyleDelete)
    {
        [self.sql_ deleteSoundFileAudioTableWhereMainID:[[self.listOfSounds objectAtIndex:indexPath.row] objectForKey:@"main_id"]]; /// delete record from DB
        [self.listOfSounds removeObjectAtIndex:indexPath.row]; /// delete record from Array
        [self updateListofSoundsFile]; /// Custom method
    }
   [self.tblView reloadData]; 
}

答案 3 :(得分:0)

说到我,我分析如下:

rmaddyNitin Gohel's回答:

  1. 在更新表之前,应始终从数据源中删除数据。

    我觉得这是理想的方式。

  2. 如果您打算致电reloadData,则根本没有理由先拨打deleteRowsAtIndexPath

    这看起来也是正确的。

  3. 我分析了歧义,如果我写reloadData它的crashishing但是一旦我写deleteRowsAtIndexPath它运作良好。

    希望有人会因为其原因等而强调这个问题。

答案 4 :(得分:0)

'removeObjectAtIndex:indexPath'需要一些时间,我怀疑你的 [self.tblView reloadData] 是在早期调用的。我尝试了一个示例代码并发现 [UiTableView beginUpdates] [UiTableView endUpdates] 的成功,如果在重新加载或删除行之前放置一点延迟,您也可以避免崩溃虽然试过了

[tableTable beginUpdates];
[tableArray removeObjectAtIndex:indexPath.row];
[tableTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableTable endUpdates];