简体   繁体   English

如何在不调用reloadData的情况下删除UITableView中的行并更新indexPath?

[英]How to delete row in UITableView and update indexPaths without calling reloadData?

[UPDATE] [更新]

I've found the problem. 我发现了问题。 I've created a custom UITableViewCell, and am not using the standard methods to trigger deletion. 我创建了一个自定义UITableViewCell,并且没有使用标准方法来触发删除。 My custom UITableViewCell has a custom indexPath property that I populate when creating the cell. 我的自定义UITableViewCell具有在创建单元格时填充的自定义indexPath属性。 That's why it doesn't get updated without a call to reload data. 这就是为什么不调用重新加载数据就不会更新它的原因。

As a workaround, to minimize code rewriting, I'm using the solution marked as the answer. 作为一种解决方法,为了最大程度地减少代码重写,我使用标记为答案的解决方案。

[/UPDATE] [/更新]

I've seen other questions similar to this, but not quite the same... 我看过其他与此类似的问题,但不完全相同...

I have a UITableView that gets it's rows (cells) from objects in a NSArray. 我有一个UITableView,它从NSArray中的对象获取行(单元格)。 The rows are mapped to the NSArray using the indexPath.row. 使用indexPath.row将行映射到NSArray。 This means that the object at index 0 in the NSArray corresponds to the cell with indexPath.row 0. 这意味着NSArray中索引0处的对象对应于indexPath.row 0的单元格。

Whenever I delete a row, I remove the object from the NSArray (as seen in many examples, including Apple's documentation). 每当我删除一行时,都会从NSArray中删除该对象(如在许多示例中所见,包括Apple的文档)。

The problem is, whenever a row is removed, the indexPath's aren't updated. 问题是,每当删除一行时,indexPath都不会更新。 For example: 例如:

I have a table view with 3 rows. 我有3行的表格视图。 This means I have indexPath.row 0, 1 and 2. Also, the corresponding NSArray objects a index 0, 1 and 2. 这意味着我有indexPath.row 0、1和2。此外,相应的NSArray对象的索引为0、1和2。

When I delete row 1 from the UITableView and remove the corresponding object in the NSArray, what remains is indexPath.row 1 and 2, but the the indexes for the NSArray are 0 and 1. 当我从UITableView中删除第1行并删除NSArray中的相应对象时,剩下的就是indexPath.row 1和2,但是NSArray的索引是0和1。

If I try to delete what is now the second row from the UITableView, I run into a problem because it's indexPath.row is 2, but the corresponding object in the NSArray has index 1. 如果我尝试从UITableView中删除第二行,则会遇到问题,因为它的indexPath.row为2,但是NSArray中的对应对象的索引为1。

To put it another way, the indexPath.row and object indexes are no longer "in sync". 换句话说,indexPath.row和对象索引不再“同步”。

People have suggested using UITableView's reloadData method... This, in fact, does "reset" the indexPaths, but interrupts the UITableView row animation. 人们建议使用UITableView的reloadData方法...实际上,这确实“重置”了indexPath,但是中断了UITableView行动画。

How can I do a row delete, update the indexPaths and still maintain the UITableView's animations?! 如何删除行,更新indexPath并仍保持UITableView的动画?

Not tested, but a couple things I can think of are either delay the reload until the animations complete. 未经测试,但我想到的几件事是将重新加载延迟到动画完成之前。 Or just reload those rows rather than the whole table using: 或者只是使用以下命令重新加载这些行而不是整个表:

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

Delay: 延迟:

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

Have a look how NSFetchedResultsControllerDelegate normally handles it: http://developer.apple.com/library/ios/#documentation/CoreData/Reference/NSFetchedResultsControllerDelegate_Protocol/Reference/Reference.html 看看NSFetchedResultsControllerDelegate通常如何处理它: http : //developer.apple.com/library/ios/#documentation/CoreData/Reference/NSFetchedResultsControllerDelegate_Protocol/Reference/Reference.html

Basically all you need to do to remove a cell from the tableview is call [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade] 基本上,从tableview中删除单元格所需要做的就是调用[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]

If you have a number changes to make wrap them with [tableView beginUpdates] and [tableView endUpdates] to trigger all the animations at once. 如果需要更改数字,请使用[tableView beginUpdates][tableView endUpdates]进行包装,以一次触发所有动画。

If this still causes an out of sync issue, just use the old trick of deleting the last indexPath first and work your way up. 如果仍然导致不同步问题,请使用旧的技巧,首先删除最后一个indexPath,然后逐步进行。 That way all the intermediate indexPaths stay valid. 这样,所有中间indexPath都保持有效。

Please, note my answer in this another thread. 请在另一个线程中记录我的答案。

UITableView delete and reload cells UITableView删除并重新加载单元格

I had some problems related to it. 我有一些与此有关的问题。 Using fixed index probably you will face a lot of headache. 使用固定索引可能会遇到很多麻烦。 I've solved this adding to the UITableViewCell a reference to a Item from my datasource, not a NSIndexPath. 我已经解决了这个问题,在UITableViewCell中添加了对我的数据源中的Item的引用,而不是NSIndexPath。 So, there is no need to use indexPath saved into your cell. 因此,无需使用保存到单元格中的indexPath。

Also, there is some information on Apple's Website saying we mustn't use the method reloadData inside insert or delete methods. 另外,Apple网站上有一些信息说,我们不能在插入或删除方法中使用reloadData方法。

Apple docs 苹果文档

all this method to reload all the data that is used to construct the table, including cells, section headers and footers, index arrays, and so on. 所有此方法将重新加载用于构造表的所有数据,包括单元格,节的页眉和页脚,索引数组等。 For efficiency, the table view redisplays only those rows that are visible. 为了提高效率,表视图仅重新显示那些可见的行。 It adjusts offsets if the table shrinks as a result of the reload. 如果表由于重新加载而缩小,则会调整偏移量。 The table view's delegate or data source calls this method when it wants the table view to completely reload its data. 当表视图的委托或数据源希望表视图完全重新加载其数据时,将调用此方法。 It should not be called in the methods that insert or delete rows, especially within an animation block implemented with calls to beginUpdates and endUpdates 不应在插入或删除行的方法中调用它,尤其是在通过调用beginUpdates和endUpdates实现的动画块中

I had a similar issue where I was assigning gesture recognizers to a cell and using the indexPath in the gesture recognizer to interact with the data source. 我遇到了一个类似的问题,即我将手势识别器分配给一个单元并在手势识别器中使用indexPath与数据源进行交互。

Instead of using the indexPath provided by tableview:cellForRowAtIndexPath: when constructing the gesture recognizer, I instead get the indexPath provided by cellForRowAtIndexPath: method on the tableView. 构造手势识别器时,我没有使用tableview:cellForRowAtIndexPath:提供的indexPath ,而是在tableView上获取了cellForRowAtIndexPath:方法提供的indexPath This approach provided the updated indexPath for a cell even if cells were added or deleted. 即使添加或删除了单元格,此方法indexPath for单元格提供了更新的indexPath for

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM