我正在尝试使用iOS 11方式在表格视图行中添加滑动操作。我想添加删除行的操作。
我的测试表视图显示0到9之间的数字,数据源是一个简单的整数数组,名为numbers
:
class ViewController: UIViewController {
var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
}
当我选择一行时,我会打印相关的numbers
:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print(numbers[indexPath.row])
tableView.deselectRow(at: indexPath, animated: true)
}
我实现了新的代理trailingSwipeActionsConfigurationForRowAt
,如下所示:
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let delete = UIContextualAction(style: .destructive, title: "Delete") { (_, _, completionHandler) in
self.numbers.remove(at: indexPath.row)
completionHandler(true)
}
return UISwipeActionsConfiguration(actions: [delete])
}
当我在一行上滑动时,删除工作正常。但是,这是我的问题,当我在删除后选择另一行时,关联的IndexPath是错误的......
示例:
我做错了什么?
答案 0 :(得分:4)
重要的是要记住,有一个模型,你的案例中的numbers
数组,以及一个视图,即显示的单元格。从numbers
中删除元素时,您只更新模型。
在大多数情况下,正如您编写的那样,之后不久会出现错误,因为模型与视图不同步。
但是,我的测试表明,当样式为.destructive
并且您将true
传递给completionHandler
时,Apple会为您删除该行。这就是你看到该行消失的原因。但是有些事情并不完全正确,我无法找到任何文件。
与此同时,只需这样做:
self.numbers.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
completionHandler(true)
永远记住,如果您使用模型进行更改,则需要更新视图。
答案 1 :(得分:0)
使用true
调用完成处理程序通过删除单元格来更新视图是非常令人困惑的,但是不更新表视图的概念,即哪个剩余单元格位于哪个索引路径。
围绕这个的文档很少,所以我运行了一个测试,发现调用完成处理程序true
FIRST 然后调用deleteRows
会导致“最正确“动画。
tableView.beginUpdates()
completion(succeeded)
users.remove(at: indexToRemove)
tableView.deleteRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
tableView.beginUpdates()
users.remove(at: indexToRemove)
tableView.deleteRows(at: [indexPath], with: .automatic)
completion(succeeded)
tableView.endUpdates()
completion(succeeded)
users.remove(at: indexToRemove)
tableView.deleteRows(at: [indexPath], with: .automatic)
users.remove(at: indexToRemove)
tableView.deleteRows(at: [indexPath], with: .automatic)
completion(succeeded)
右侧面板的剩余单元格被正在移除的单元格部分覆盖,而左下方面板则从某处显示白色视图。