我承认 UITableview 在用户滚动时动态加载一个单元格。我想知道是否有一种方法可以预加载所有单元格,以便在滚动时不加载每个单元格。我需要预加载 10 个单元格。这可能吗?
5 回答
您可以初始化表格视图单元格,将它们放入数组precomputedCells
中,并在数据源委托方法tableView:cellForRowAtIndexPath:
中从数组中返回预先计算的单元格,而不是调用dequeueReusableCellWithIdentifier:
. (类似于您在静态表格视图中所做的事情。)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [self.precomputedCells objectAtIndex:indexPath.row];
}
看看 WWDC 2012 Session 211 “Building Concurrent User Interfaces on iOS”可能也很有用,其中展示了如何在后台线程中填充表格视图单元格的内容,同时保持用户界面响应。
我正在寻找原始问题的解决方案,我想我会分享我的解决方案。
就我而言,我只需要预加载下一个单元格(我不会详细说明原因,但有一个很好的理由)。
似乎 UITableView 呈现尽可能多的单元格,以适应分配给它的 UITableView 框架。
因此,我将 UITableView 框架超大了 1 个额外单元格的高度,将过大的区域推到了屏幕外(或者如果需要,它可以进入剪辑的 UIView)。当然,这意味着当我滚动表格视图时,最后一个单元格将不可见(因为 UITableView 框架大于它的超级视图)。因此,我在单元格高度的 tableFooterView 中添加了一个额外的 UIView。这意味着当表格滚动到底部时,最后一个单元格很好地位于其超级视图的底部,而添加的 tableFooterView 保持在屏幕外。
这当然可以应用于任何数量的细胞。如果需要,甚至可以通过将 UITableView 框架超大到 iOS 最初计算的 contentSize,然后添加相同大小的 tableFooterView 来应用它来预加载所有单元格。
希望这可以帮助其他有同样问题的人。
正如 Mark 所建议的,我还临时更改了 UITableView 的高度,以便表格视图创建足够的可重用单元格。然后我重置了我的表格视图的高度,以便它在滚动时停止创建可重用的单元格。
为此,我创建了一个默认设置为 false 的 helper bool:
var didPreloadCells = false
当我的表格视图第一次重新加载数据并因此创建第一个可重用单元格时,它设置为 true。
resultsHandler.doSearch { (resultDict, error) -> Void in
[...]
self.tableView.reloadData()
self.didPreloadCells = true
[...]
}
真正的技巧发生在我的 viewDidLayoutSubviews 方法中。在这里,我根据布尔值设置表格视图的框架。如果尚未创建可重用单元格,我会增加表格视图的框架。在另一种情况下,我设置了正常框架
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.tableView.frame = self.view.bounds
if !didPreloadCells
{
self.tableView.frame.size.height += ResultCellHeight
}
}
借助该表视图创建的初始可重用单元格比正常情况多,并且滚动流畅流畅,因为不需要创建额外的单元格。
Change the dequeueReusableCellWithIdentifier when you are reusing the table view otherwise it will load the old data
自动调整单元格的解决方案。将“estimatedRowHeight”更改为较低的值
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 32; //Actual is 64
}
实际估计高度为 64。32 用于添加更多单元格以供重复使用,以避免滚动开始时出现滞后