我有一个 UICollectionView 显示从网络检索到的图像。它们是异步下载的。
当用户快速滚动时,他们会看到占位符,直到单元格加载。似乎 UICollectionView 只加载可见的内容。
有没有办法说“集合视图,在上方和下方多加载 20 个单元格”所以当用户在不滚动的情况下查看内容时加载更多单元格的机会更高?
我有一个 UICollectionView 显示从网络检索到的图像。它们是异步下载的。
当用户快速滚动时,他们会看到占位符,直到单元格加载。似乎 UICollectionView 只加载可见的内容。
有没有办法说“集合视图,在上方和下方多加载 20 个单元格”所以当用户在不滚动的情况下查看内容时加载更多单元格的机会更高?
这个想法是让 VC 识别何时可能需要远程加载并启动它。唯一棘手的部分是保持正确的状态,这样你就不会触发太多。
假设您的收藏是垂直的,您想知道的条件是:
BOOL topLoad = scrollView.contentOffset.y < M * scrollView.bounds.size.height
或者什么时候
BOOL bottomLoad = scrollView.contentOffset.y > scrollView.contentSize.height - M * scrollView.bounds.size.height
换句话说,当我们距离内容边缘有 M 个“页面”时。但在实践中,这种情况会被过度触发,例如当您第一次加载时,或者如果您正在测试它scrollViewDidScroll
,您不想为用户滚动的每个像素生成 Web 请求。
因此,正确处理需要在视图控制器中添加额外的状态。vc 可以有一对 BOOL,如 topLoadEnabled、bottomLoadEnabled,在视图准备好之前为 NO。然后,滚动委托代码如下所示:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// compute topLoad and bottomLoad conditions
if (topLoad && self.topLoadEnabled) [self startTopLoad];
底部也是如此。加载代码抽象地看起来像这样:
self.topLoadEnabled = NO; // don't trigger more loading until we're done
[self.model getMoreTopStuff:^(NSArray *newStuff, NSError *error) {
// do view inserts, e.g. tableView.beginUpdates
self.topLoadEnabled = YES;
}];
底部的想法相同。我们希望模型自己获取(也许模型有图像 url)并缓存结果(然后模型有图像)。作为视图的数据源,视图控制器被调用来配置视图单元。我可以天真地向模型询问图像。该模型应该回答获取的图像或占位符。
希望这是有道理的。
在我看来,您做出了错误的假设:单元格只是视图,因此您不应将它们视为模型对象。UICollectionView 和 UITableView 非常高效,因为它们不断回收单元格,因此您应该考虑在业务方面预加载内容。创建交互器或视图模型对象并用它们填充您的数据源,然后如果您仍然希望这样做,您将能够要求这些对象预加载图像。
BOOL 标志很少是答案。我宁愿去估计一个合理的页面大小并根据需要从cellForItemAtIndePath
方法中获取图像。