同时插入和删除 UITableViewCell 不起作用

Posted

技术标签:

【中文标题】同时插入和删除 UITableViewCell 不起作用【英文标题】:Inserting and deleting UITableViewCell at the same time not working 【发布时间】:2008-12-01 19:55:06 【问题描述】:

我在从同一个 UITableView 插入和删除 UITableViewCells 时感到很痛苦!

我通常不发布代码,但我认为这是显示问题所在的最佳方式:


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    return 5;



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

    if (iSelectedSection == section) return 5;
    return 1;



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

    //NSLog(@"drawing row:%d section:%d", [indexPath row], [indexPath section]);

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    

    if (iSelectedSection == [indexPath section]) 
        cell.textColor = [UIColor redColor];
     else 
        cell.textColor = [UIColor blackColor];
       


    cell.text = [NSString stringWithFormat:@"Section: %d Row: %d", [indexPath section], [indexPath row]];

    // Set up the cell
    return cell;



- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    // Navigation logic -- create and push a new view controller

    if ([indexPath row] == 0) 

        NSMutableArray *rowsToRemove = [NSMutableArray array];
        NSMutableArray *rowsToAdd = [NSMutableArray array];

        for(int i=0; i<5; i++) 

            //NSLog(@"Adding row:%d section:%d ", i, [indexPath section]);
            //NSLog(@"Removing row:%d section:%d ", i, iSelectedSection);

            [rowsToAdd addObject:[NSIndexPath indexPathForRow:i inSection:[indexPath section]]];
            [rowsToRemove addObject:[NSIndexPath indexPathForRow:i inSection:iSelectedSection]];

        

        iSelectedSection = [indexPath section];

        [tableView beginUpdates];
        [tableView deleteRowsAtIndexPaths:rowsToRemove withRowAnimation:YES];
        [tableView insertRowsAtIndexPaths:rowsToAdd withRowAnimation:YES];
        [tableView endUpdates];

    


此代码创建 5 个部分,第一个(从 0 开始索引)有 5 行。当您选择一个部分时 - 它会从您之前选择的部分中删除行并将行添加到您刚刚选择的部分。

如图所示,当我加载应用程序时,我有这样的东西:

http://www.freeimagehosting.net/uploads/1b9f2d57e7.png http://www.freeimagehosting.net/uploads/1b9f2d57e7.png

图片在这里:http://www.freeimagehosting.net/uploads/1b9f2d57e7.png

选择第 2 节的表第 0 行后,我删除第 1 节的行(默认选中)并添加第 2 节的行。但我得到了:

http://www.freeimagehosting.net/uploads/6d5d904e84.png http://www.freeimagehosting.net/uploads/6d5d904e84.png

图片在这里:http://www.freeimagehosting.net/uploads/6d5d904e84.png

...这不是我所期望的!似乎第 2 部分的第一行以某种方式保留了 - 即使它肯定被删除了。

如果我只是做一个 [tableView reloadData],一切都会正常显示...但我显然放弃了漂亮的动画。

如果有人能在这里发光,我将不胜感激!这让我有点发疯!

再次感谢, 尼克。

【问题讨论】:

【参考方案1】:

努力让它发挥作用。这是我在 tableView 中添加一行的代码:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[tableView beginUpdates];
[dataSource insertObject:[artistField text] atIndex:0];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
[tableView endUpdates];

【讨论】:

【参考方案2】:

我似乎记得 numberOfRowsInSection: 会在您调用 deleteRows 或 insertRow 时被调用,您需要非常小心实际 numberOfRowsInSection cliams 是否与您的更改相匹配。在这种情况下,您可能想尝试移动 iSelectedSection = [indexPath section];行到 endUpdates 之后。

【讨论】:

【参考方案3】:

我不记得我在哪里读到了这篇文章,但我相信您不应该从表视图委托函数之一执行表行更新(插入和删除)。我认为更好的选择是执行 performSelectorOnMainThread 传递作为对象执行更新所需的必要信息。比如:

- (void)tableView:(UITableView *)tableView 
  didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    // ....
    [self performSelectorOnMainThread: @selector(insertRows:)
                           withObject: someObjectOrNil]; // double check args


- (void) insertRows: (NSObject*)someObjectOrNil 
    [tableView beginUpdates];
    // update logic
    [tableView endUpdates];

    // don't call reloadData here, but ensure that data returned from the 
    // table view delegate functions are in sync

【讨论】:

【参考方案4】:

在您发布的代码中,您的循环索引从 0 运行到 4,这表明它将删除第 1 节中的所有行,然后在第 2 节中添加五个新行。因为每个部分已经有第 0 行,这会将第 2 部分第 0 行的 第二个 实例添加到表中。

我建议让您的循环从 1 运行到 4:

for (int i=1; i<5; i++)

    // ...

【讨论】:

嘿 eJames,感谢您的评论 - 一个非常有效的观点!我想了一分钟它可能会解决我的问题 - 但我仍然遇到同样的问题。我认为实际上可能有 iPhone,但是当您尝试从一个部分删除项目并同时将它们添加到另一个部分时......【参考方案5】:

仅供参考:此错误似乎已在 2.2 iPhone 更新中完全修复。 感谢苹果! 缺口。

【讨论】:

以上是关于同时插入和删除 UITableViewCell 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

插入 UITableViewCell 不起作用

为啥不应该在删除/插入行的方法上调用 reloadData

UITableViewCell 删除按钮动画

同时删除和插入记录 PHP

无法使用 uiimageview 同时满足 uitableviewcell 中的约束

CoreData 在插入和删除时崩溃同时发生