我使用具有相对“重”自定义表格视图单元格的表格视图 - 比如在单个单元格中有大约100个子视图(完整层次结构)。尽管如此,我已经能够实现非常流畅的滚动 - 使用标准做法,例如仅使用不透明视图,隐藏未使用的子视图(甚至从视图层次结构中移除),预加载单元格高度等。
问题是创建单个单元实例的成本仍然相对较高。由于标准UITableView的单元重用逻辑如何工作,这个问题仅在特定条件下才会显着。
通常在加载表视图(并显示初始内容)时,它会创建几乎所有必需的单元格实例 - 因此当您开始滚动时,很少需要创建任何可重用的单元格。但是如果由于某种原因它只在开始时显示一些单元格,那么在启动滚动时显然需要创建更多单元格。在我的情况下,如果有一个宽的表视图标题或第一个单元格足够大,这是显而易见的。一旦你开始滚动就会发生这种情况,会有一段时间明显滞后,这显然是由创建的新单元实例引起的。没有什么比这更难看但仍然明显,特别是与之后的绝对平滑滚动相比。
现在显而易见的解决办法就是让细胞“更轻” - 就像把它们分成不同的更具体的类型,这样每个都可以包含更少的子视图。但是由于我的内容的组织方式是一个非常复杂的解决方案。
所以我的问题是 - 是否有任何好的方法可以“欺骗”表格视图逻辑以立即强制加载和缓存特定数量的可重用单元格实例 - 尽管实际可见的单元格数量是多少?
我一直在考虑的一个选项是拥有自己的显式单元格缓存,并在需要时用单元格预先填充它(例如在-viewDidLoad中)。我对这种方法的问题是你必须事先知道你需要的确切类型的细胞 - 对我来说效果不好。改进将是在加载初始数据时构建缓存(因此至少知道确切的内容类型),但我一直在想是否有任何简单的选项。
答案 0 :(得分:3)
您可以通过将自己的“二级缓存”图层添加到数据源来实现。
初始化数据源时,根据需要预先创建任意数量的单元格,并将它们放入数组中。当您的dequeueReusableCellWithIdentifier
失败时,请首先转到该阵列,然后从那里取出一个单元格。一旦阵列耗尽,开始创建新单元格(如果您预先创建了足够的单元格,则不需要动态创建新单元格:当有足够的单元格旋转进出可见性时,出列将最终停止失败。)< / p>
答案 1 :(得分:0)
我也有类似的情况,我想在不同的单元格中加载几个网站,并且必须只触发一次loadrequest。想法是通过向上或向下滚动使单元格变得可见/不可见时避免重复调用。说我的tableview中有5个单元格,每个单元格都有一个webview,可以加载不同的网站。 loadrequest将被调用一次,cell将被缓存。这是最简单的实现。
变量声明
let weblinks:[String] = ["http://www.google.com",
"http://www.facebook.com",
"http://www.yahoo.com",
"http://www.puthiyathalaimurai.com/",
"http://www.github.com"]
var mycells:[MyTableViewCell] = [MyTableViewCell(),
MyTableViewCell(),
MyTableViewCell(),
MyTableViewCell(),
MyTableViewCell()]
CellForRow。我希望你知道它的作用,
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = String(describing: MyTableViewCell.self)
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier) as? MyTableViewCell
if cell?.isNewCell == true { //return from cache
return mycells[indexPath.row]
}
cell?.title.text = weblinks[indexPath.row].uppercased()
cell?.web.loadRequest(URLRequest(url: URL(string: weblinks[indexPath.row])!))
cell?.isNewCell = true //mark it for cache
mycells[indexPath.row] = cell!
return cell!
}