【发布时间】:2021-02-10 02:56:16
【问题描述】:
我希望UITableView 的刷新由新单元格的出现触发。
简单的设置。 UITableView,dataSource 是 [Double]。表格中的每一行将在数组中显示一个数字。
我想做的特别的事情是我希望表格用所有可见单元格的最大数量标记单元格。然后每个其他单元格将计算与屏幕上的最大数量的差异。并且每次出现新单元格时都会更新。
import UIKit
class ViewController: UIViewController {
var max = 0.0
var data:[Double] = [13,32,43,56,91,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() {
// calculate the max of visible cells
let indexes = tableView.indexPathsForVisibleRows!
max = indexes
.map { data[$0.row] }
.reduce(0) { Swift.max($0,$1) }
// trying to update all the visible cells.
// tableView.reloadRows(at: indexes, with: .none) ****
// tableView.reloadData() ****
}
}
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]) : \(max)"
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()
}
}
我做了什么
有2行代码,末尾带有****标记。
如果我取消注释 tableView.reloadRows(at: indexes, with: .none),Xcode 会产生错误:'NSRangeException', reason: '*** -[__NSArrayM objectAtIndexedSubscript:]: index 15 beyond bounds [0 .. 13]'。我真的不明白为什么,但我知道屏幕上的可见单元格最多为 14 个以适合屏幕,但在表格加载阶段,模拟器认为在某些时候有 19 个可见单元格
如果相反,我取消注释tableView.reloadData(),这行代码将触发willDisplay func,它将再次调用calculate func,其中包含reloadData()。这是一个无限递归循环,屏幕上没有成功显示任何行。
如果我不取消任何注释,表格将不会更新屏幕上已经显示的单元格。只有新出现的单元格才能正确显示我想要的效果。
感谢您阅读所有内容并尝试提供帮助。
【问题讨论】:
-
您无法重新加载单元格,因为这将触发无限循环。在
willDisplayCell中,您可以使用cellForRow(at:)获取当前屏幕上的单元格并直接对其进行更新。 -
@Paulw11,非常感谢您的回复。所以我删除了
didEndDisplaying。我将calculate()中的所有内容添加到willDisplay中,并添加了额外的代码,该代码使用for 循环来查找所有使用indexes的单元格,并将它们的textLabel.text设置为新字符串和cell.setNeedsDisplay(),但似乎这样设置新文本的代码被忽略了。
标签: ios swift uitableview reloaddata