В моем случае использования ячейка перемещается в indexPath 0-0, а затем удаляется из массива. Оба действия заключены в beginUpdates()
endUpdates()
. Это вызывает проблемы с willDisplay
и didEndDisplaying
.
Иногда didEndDisplaying
даже не вызывается или willDisplay
вызывается два или более раз, что делает мою клетку ограниченной несколько раз.
Вот пример проекта: https://github.com/mNijurin/table_playground
Этот проект добавляет «1» в willDisplay
и удаляет его в didEndDisplaying
из метки в ячейке. Так что ни в коем случае мы не должны видеть что-то вроде пустой строки или нескольких «11».
Когда нажата кнопка «do», программа переместит строку 50 в indexPath 0-0 и удалит ее.
Прокрутите до 50 строк и нажмите «сделать», все ячейки на экране будут ограничены дважды. Мы можем проверить это с помощью надписей "11"
Вот видео: https://youtu.be/nCWkk2eLDWc
А вот и код:
var texts = [String]()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "do", style: .plain, target: self, action: #selector(doSome))
navigationController?.navigationBar.isOpaque = true
for i in 0...100 {
texts.append("\(i)")
}
}
@objc func doSome() {
let text = texts[50]
texts.remove(at: 50)
texts.insert(text, at: 0)
tableView.beginUpdates()
tableView.moveRow(at: IndexPath(row: 50, section: 0), to: IndexPath(row: 0, section: 0))
tableView.endUpdates()
texts.remove(at: 0)
tableView.beginUpdates()
tableView.deleteRows(at: [IndexPath(row: 0, section: 0)], with: .bottom)
tableView.endUpdates()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return texts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let someCell = tableView.dequeueReusableCell(withIdentifier: "cell") {
return someCell
} else {
let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
let label = UILabel(frame: CGRect(x: 50, y: 0, width: 300, height: 40))
label.textColor = .black
label.tag = 13
cell.textLabel?.addSubview(label)
return cell
}
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
print("bind row: \(indexPath.row) \(Unmanaged.passUnretained(cell).toOpaque())")
cell.textLabel?.text = texts[indexPath.row]
let label = cell.contentView.viewWithTag(13) as? UILabel
label?.text = "\(label?.text ?? "")1"
print("willDisplay \(label?.text ?? "")")
}
override func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
print("unbind row: \(indexPath.row) \(Unmanaged.passUnretained(cell).toOpaque())")
cell.textLabel?.text = nil
let label = cell.contentView.viewWithTag(13) as? UILabel
if let text = label?.text, text.count == 1 {
label?.text = ""
} else if let text = label?.text, text.count > 0 {
var text = text
text.remove(at: text.index(text.endIndex, offsetBy: -1))
label?.text = text
}
print("endDisplay \(label?.text ?? "")")
}
`