所以我UITableViewDataSource
使用NSFetchedResultsController
.
然后我修改核心数据库的内容,NSFetchedResultsController
然后更新 tableView..
无论如何要知道 tableView 何时完成重新加载数据?
我们有一个针对 REST 实现进行缓存的复杂数据模型,很难确定我们是否需要获取更多数据来填满屏幕(因为屏幕可能对加载的原始数据使用复杂的过滤器)。此外,UITableViewCell
不能保证对象的高度相同。
简单的答案是简单地将数据转储到核心数据,并使用NSFetchedResultsController
将数据提供给UITableView
.
下面是它的工作原理:
- 我们添加了一个 tableview.tableFooterView 来显示我们的“数据加载”消息。
- 从 REST API 加载一批数据,然后使用它更新我们的核心数据对象。
这会触发触发的
controllerDidChangeContent
方法,然后触发一个tableView reloadData (eg:)- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { [self.tableView reloadData]; }
然后我们基本上然后通过调用如下方法“检查”250 毫秒后页脚是否仍然可见:
[self performSelector:@selector(checkIfFooterViewIsVisible) withObject:nil afterDelay:0.25]; - (void)checkIfFooterViewIsVisible { BOOL viewVisible = CGRectIntersectsRect(self.tableView.bounds,self.tableView.tableFooterView.frame); if (viewVisible) { [self getMoreData]; }
我们还会在每次滚动时检查页脚是否在视图中。
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { [self checkIfFooterViewIsVisible]; }
- 如果我们加载“最后一批”数据,我们实际上只是
tableViewFooter
从表中删除了视图对象(因此它永远不可见)。
所以答案很酷,因为我们可以确定是否需要提取更多数据,前提是用户“需要”它。要么是因为第一批没有太多可见数据,要么是因为他们向下滚动并想要更多数据。检查当前位置tableFooterView
可以让我们知道我们是否在屏幕上“绘制”了足够的数据。
问题是 - 我可以摆脱:
[self performSelector:@selector(checkIfFooterViewIsVisible) withObject:nil afterDelay:0.25];
如果我们将延迟设置得太快,则UITableView
没有时间更新屏幕(并更改页脚的位置)。如果我们更新太慢,那么感觉就像应用程序在加载数据时“卡顿”一样,并且加载数据的速度可能比它可以加载的慢。但是不同的 iOS 设备(以及不同的网络覆盖范围)意味着时间会略有不同,因此“让UITableView
更新并稍后检查”大部分时间都有效,但我觉得这可以更顺畅。
无论如何(可能通过重载UITableView
)我们可以确定UITableView
“完成”加载UITableViewCell
对象吗?(至少直到下一次滚动移动?)。添加这个奇怪的延迟效果很好,但如果我们明确知道[tableview reloadDate]
操作已经完成,它会更干净。