ios UITableView 的 reloadRowsAtIndexPaths: (NSArray *) indexPaths 无法导致重新加载,除非你调用它两次?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5557504/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UITableView's reloadRowsAtIndexPaths: (NSArray *) indexPaths failing to cause a reload unless you call it twice?
提问by William Jockusch
I have a UITableViewController managing a UITableView object in an iPad app. The table view is tied in with a rather complicated constellation of other objects. I am having a problem when I ask it to reload a row as follows:
我有一个 UITableViewController 在 iPad 应用程序中管理 UITableView 对象。表格视图与其他对象的相当复杂的星座联系在一起。当我要求它重新加载一行时遇到问题,如下所示:
//indexPath is an NSIndexPath with indexes 0 and 0. At the moment, this is the only cell in the table view.
NSArray *array = [NSArray arrayWithObject:indexPath];
[self.tableView reloadRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationNone];
The problem is that the row does not reload. There is never a callback to cellForRowAtIndexPath.
问题是该行不会重新加载。从来没有对 cellForRowAtIndexPath 的回调。
The crazy thing is that if I call reloadRowsAtIndexPaths twice, the second call does trigger the reload:
疯狂的是,如果我调用 reloadRowsAtIndexPaths 两次,第二次调用会触发重新加载:
//indexPath is an NSIndexPath with indexes 0 and 0. At the moment, this is the only cell in the table view.
NSArray *array = [NSArray arrayWithObject:indexPath];
[self.tableView reloadRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationNone]; // does not reload
[self.tableView reloadRowsAtIndexPaths:array withRowAnimation:UITableViewRowAnimationNone]; // does reload
I am wondering if anyone else has ever encountered a bug like this, and if so, what was the cause?
我想知道是否有其他人遇到过这样的错误,如果有,原因是什么?
回答by amattn
reloadRowsAtIndexPaths:...
only works when wrapped inbetween calls to:
reloadRowsAtIndexPaths:...
仅在对以下调用之间进行包装时才有效:
- (void)beginUpdates;
- (void)endUpdates;
Outside of that, behavior is undefined. (and as you've discovered, fairly unreliable).
除此之外,行为是未定义的。(正如你所发现的,相当不可靠)。
Edit: quoting relevant part of "Table View Programming Guide for iPhone OS":
编辑:引用“iPhone OS 表视图编程指南”的相关部分:
To animate a batch insertion and deletion of rows and sections, call the insertion and deletion methods within an animation block defined by successive calls to beginUpdates and endUpdates. If you don't call the insertion and deletion methods within this block, row and section indexes may be invalid. beginUpdates...endUpdates blocks are not nestable.
At the conclusion of a block—that is, after endUpdates returns—the table view queries its data source and delegate as usual for row and section data. Thus the collection objects backing the table view should be updated to reflect the new or removed rows or sections.
The reloadSections:withRowAnimation: and reloadRowsAtIndexPaths:withRowAnimation: methods, which were introduced in iPhone OS 3.0, are related to the methods discussed above. They allow you to request the table view to reload the data for specific sections and rows instead of loading the entire visible table view by calling reloadData.
要动画批量插入和删除行和节,请在由连续调用 beginUpdates 和 endUpdates 定义的动画块内调用插入和删除方法。如果不调用此块内的插入和删除方法,行和节索引可能无效。beginUpdates...endUpdates 块不可嵌套。
在块结束时——即在 endUpdates 返回之后——表视图像往常一样查询其数据源和委托以获取行和节数据。因此,应该更新支持表视图的集合对象以反映新的或删除的行或部分。
在 iPhone OS 3.0 中引入的 reloadSections:withRowAnimation: 和 reloadRowsAtIndexPaths:withRowAnimation: 方法与上面讨论的方法有关。它们允许您请求表视图重新加载特定部分和行的数据,而不是通过调用 reloadData 加载整个可见表视图。
回答by R_B
I know this topic is kind of old, but I came across the same issue and a simple fix. I had a table view and when I called reloadData and/or reloadRowsAtIndexPaths, the tableview method cellForRowAtIndexPath would not fire.
It turns out I hadn't hooked up my tableview IBOutlet in Interface Builder - once that was hooked up everything fired as expected. It's always the little things...
Also, like others have mentioned, if you only need the one call, wrapping it in begin/endUpdates isn't necessary.
我知道这个话题有点老,但我遇到了同样的问题和一个简单的修复。我有一个表格视图,当我调用 reloadData 和/或 reloadRowsAtIndexPaths 时,表格视图方法 cellForRowAtIndexPath 不会触发。
事实证明,我没有在 Interface Builder 中连接我的 tableview IBOutlet - 一旦连接好,一切都按预期启动。它总是小事情......
此外,就像其他人提到的那样,如果您只需要一个电话,则不需要将其包装在 begin/endUpdates 中。