如何删除UITableView中的行并更新indexPaths而不调用reloadData?

时间:2013-04-26 19:10:07

标签: ios uitableview animation row

[UPDATE]

我发现了问题。我已经创建了一个自定义的UITableViewCell,并没有使用标准方法来触发删除。我的自定义UITableViewCell有一个自定义indexPath属性,我在创建单元格时填充该属性。这就是为什么没有调用重新加载数据就不会更新的原因。

作为一种解决方法,为了最大限度地减少代码重写,我使用标记为答案的解决方案。

[/ UPDATE]

我见过类似的其他问题,但不完全一样......

我有一个UITableView,可以从NSArray中的对象获取行(单元格)。使用indexPath.row将行映射到NSArray。这意味着NSArray中索引0处的对象对应于indexPath.row为0的单元格。

每当我删除一行时,我都会从NSArray中删除该对象(如许多示例所示,包括Apple的文档)。

问题是,每当删除一行时,indexPath都不会更新。例如:

我有一个包含3行的表格视图。这意味着我有indexPath.row 0,1和2.此外,相应的NSArray对象索引0,1和2.

当我从UITableView中删除第1行并删除NSArray中的相应对象时,剩下的是indexPath.row 1和2,但NSArray的索引是0和1。

如果我尝试从UITableView中删除现在的第二行,我遇到了一个问题,因为它的indexPath.row是2,但NSArray中的相应对象的索引为1。

换句话说,indexPath.row和对象索引不再“同步”。

人们建议使用UITableView的reloadData方法......事实上,这会“重置”indexPaths,但会中断UITableView行动画。

如何进行行删除,更新indexPaths并仍然维护UITableView的动画?!

4 个答案:

答案 0 :(得分:4)

未经测试,但我能想到的一些事情要么是在动画完成之前延迟重新加载。或者只使用以下命令重新加载这些行而不是整个表:

- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation

延迟:

[tableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.5];

答案 1 :(得分:2)

了解NSFetchedResultsControllerDelegate如何正常处理它:http://developer.apple.com/library/ios/#documentation/CoreData/Reference/NSFetchedResultsControllerDelegate_Protocol/Reference/Reference.html

基本上,从tableview中删除单元格所需要做的就是调用[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]

如果您进行了数字更改,请使用[tableView beginUpdates][tableView endUpdates]对其进行换行,以便立即触发所有动画。

如果仍然导致不同步问题,只需先使用删除最后一个indexPath的旧技巧,然后逐步完成。这样,所有中间indexPath都保持有效。

答案 2 :(得分:0)

请在另一个帖子中注意我的答案。

UITableView delete and reload cells

我遇到了一些与之相关的问题。使用固定索引可能会遇到很多麻烦。我已经解决了这个问题,在UITableViewCell中添加了一个来自我数据源的Item的引用,而不是NSIndexPath。因此,无需使用保存在单元格中的indexPath。

另外,Apple网站上有一些信息说我们不能在插入或删除方法中使用reloadData方法。

Apple docs

  

所有这些方法重新加载用于构造表的所有数据,包括单元格,节头和页脚,索引数组等。为了提高效率,表视图仅重新显示可见的行。如果表因重新加载而缩小,它会调整偏移量。表视图的委托或数据源在希望表视图完全重新加载其数据时调用此方法。不应在插入或删除行的方法中调用它,尤其是在通过调用beginUpdates和endUpdates实现的动画块中

答案 3 :(得分:0)

我遇到了类似的问题,我将手势识别器分配给一个单元格,并使用手势识别器中的indexPath与数据源进行交互。

而不是在构建手势识别器时使用indexPath提供的tableview:cellForRowAtIndexPath:,而是在tableView上获取indexPath方法提供的cellForRowAtIndexPath:。即使添加或删除了单元格,此方法也会提供更新的indexPath for单元格。