ios - 每次新单元出现时如何访问 UITableView.visibleCells
问题描述
我有一个 tableView 显示[Double]
。很简单。但我也想显示每一行屏幕上数字的平均值,以及这个数字和平均值之间的差异。
因为每次出现新行都需要重新计算平均值,所以我正在考虑tableView.visibleCells
在cellForRowAt: indexPath
方法中访问,然后更新该行和屏幕上每隔一行的平均值,因为屏幕上的行的平均值应该是相同的对于所有屏幕上的行。
但后来我收到了这个错误信息 [Assert] Attempted to access the table view's visibleCells while they were in the process of being updated, which is not allowed. Make a symbolic breakpoint at UITableViewAlertForVisibleCellsAccessDuringUpdate to catch this in the debugger and see what caused this to occur. Perhaps you are trying to ask the table view for the visible cells from inside a table view callback about a specific row?
虽然这很响亮,但我想知道正确的方法或解决方法是什么?
代码很简单
class ViewController: UIViewController {
var data:[Double] = [13,32,43,56,89,42,26,17,63,41,73,54,26,87,64,33,26,51,99,85,57,43,30,33,20]
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.dataSource = self
self.tableView.delegate = self
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "default")!
cell.textLabel?.text = "\(data[indexPath.row])"
print(tableView.visibleCells.count) // THIS LINE PRODUCE ERROR
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 64
}
}
我试过的:
我已经尝试过didEndDisplaying
,willDisplay
当我添加print(tableView.visibleCells.count)
到其中任何一个时,都会返回相同的错误消息。
解决方案
回答:
你可以使用 UITableView 的委托函数来计算这个。
tableView(_:willDisplay:forRowAt:)
每次在单元格变得可见之前都会调用,因此您可以在此时重新计算平均值。此外,tableView(_:didEndDisplaying:forRowAt:)
当单元格不显示时会触发,也可用于重新计算。
文档:
tableView(_:willDisplay:forRowAt:)
tableView(_:didEndDisplaying:forRowAt:)
升级版:
计算使用tableView.indexPathsForVisibleItems
例子:
import UIKit
class ViewController: UIViewController {
var data:[Double] = [13,32,43,56,89,42,26,17,63,41,73,54,26,87,64,33,26,51,99,85,57,43,30,33,20]
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
self.tableView.dataSource = self
self.tableView.delegate = self
self.tableView.reloadData()
}
private func calculate() {
let count = tableView.indexPathsForVisibleRows?.count
let sum = tableView.indexPathsForVisibleRows?
.map { data[$0.row] }
.reduce(0) { $0 + $1 }
if let count = count, let sum = sum {
print(sum / Double(count))
}
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "default")!
cell.textLabel?.text = "\(data[indexPath.row])"
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 64
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
calculate()
}
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
calculate()
}
}
推荐阅读
- javascript - 如何导入@material/theme 和@material/textfield 样式来创建自己的主题包
- javascript - 如何以及在哪里使用 Chrome.storage API 在 chrome 扩展程序中存储用户首选项?
- java - 为什么 array.sort 对这样的数组不起作用?
- php - 购物车页面中插件的货币转换错误
- android - 为 Android 开发配置 Qt Creator
- javascript - for 循环中的 await 是否会阻塞主线程,直到整个操作完成?
- laravel - 我需要 Laravel 控制器优化方面的帮助
- acumatica - 使用 PXFormula 显示未绑定字段
- android-studio - Flutter 项目的权限被拒绝
- slack - 在不通知所有频道的情况下设置提醒@chanel