2

所以我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]操作已经完成,它会更干净。

4

0 回答 0