如何解决如何在相同的beginUpdates / endUpdates操作中移动和重新加载UITableView行?
我正在UITableView上进行非常复杂的更新。可以同时移动,删除,插入和更改多行。在同一tableView.beginUpdates()
/ tableView.endUpdates()
区块内处理这些更改的正确方法是什么?
示例:
Data before update ==> Data after update
================== =================
0: zero 0: zero
1: one 1: 555 (updated element five)
2: two 2: three
3: three 3: 222 (updated element two)
4: four
5: five
==> Elements 1 and 4 are deleted
==> Elements 2 and 5 are updated (content changes) and they switch their position
这可以使用一个简单的ViewController完成:
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
@IBOutlet var tableView: UITableView!
@IBOutlet var button: UIButton!
var rowTitles = ["zero","one","two","three","four","five"]
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
return rowTitles.count
}
func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell",for: indexPath)
cell.textLabel?.text = rowTitles[indexPath.row]
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self,forCellReuseIdentifier: "cell")
}
@IBAction func click() {
tableView.beginUpdates()
// "zero","555","222"
rowTitles[2] = "555"
rowTitles[5] = "222"
// "zero","222"
rowTitles.remove(at: 1)
// "zero","222"
rowTitles.remove(at: 3)
// Delete "one" (original index = 1)
tableView.deleteRows(at: [IndexPath(row: 1,section: 0)],with: .automatic)
// Delete "four" (original index = 4)
tableView.deleteRows(at: [IndexPath(row: 4,with: .automatic)
// Move "two" and "five",use new old index for source and new index for destination
tableView.moveRow(at: IndexPath(row: 2,section: 0),to: IndexPath(row: 3,section: 0))
tableView.moveRow(at: IndexPath(row: 5,to: IndexPath(row: 1,section: 0))
// CRASH
//tableView.reloadRows(at: [IndexPath(row: 5,with: .automatic)
tableView.endUpdates()
}
}
一切正常,除了同时移动和重新加载第2行和第5行之外。我没有使用reloadRows(...)
,代码运行了,但结果为列表zero,five,three,two
。因此,元素的顺序正确,但是行尚未更新为555
和222
。
在将reloadRows(...)
与原始索引2和5一起使用时,该应用程序崩溃,因为已为相同的索引调用了move + delete(似乎重新加载在内部被视为delete + add)。
在reloadRows(...)
之后使用endUpdates()
可以得到正确的结果。但是,我想知道这是否是正确的方法。关于Apple文档reloadRows(...)
应该在beginUpdates ... endUpdates
中调用。
那么,解决此问题的正确方法是什么?
解决方法
不确定要使用哪种视觉效果,但是...
您可能想重新加载表格视图,然后然后删除/重新排列行。
尝试这样:
@IBAction func click() {
rowTitles[5] = "555"
rowTitles[2] = "222"
let p1 = IndexPath(row: 2,section: 0)
let p2 = IndexPath(row: 5,section: 0)
self.tableView.reloadRows(at: [p1,p2],with: .automatic)
rowTitles.remove(at: 1)
rowTitles.remove(at: 3)
// need to update order in array
rowTitles[1] = "555"
rowTitles[3] = "222"
tableView.performBatchUpdates({
// Delete "one" (original index = 1)
tableView.deleteRows(at: [IndexPath(row: 1,section: 0)],with: .automatic)
// Delete "four" (original index = 4)
tableView.deleteRows(at: [IndexPath(row: 4,with: .automatic)
// Move "two" and "five",use new old index for source and new index for destination
tableView.moveRow(at: IndexPath(row: 2,section: 0),to: IndexPath(row: 3,section: 0))
tableView.moveRow(at: IndexPath(row: 5,to: IndexPath(row: 1,section: 0))
},completion: { _ in
// if you want to do something on completion...
})
}
最终结果顺序为:
zero
555
three
222
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。