删除行后更新 indexPath 值

Posted

技术标签:

【中文标题】删除行后更新 indexPath 值【英文标题】:Update indexPath value after deleting a row 【发布时间】:2020-08-14 16:16:46 【问题描述】:

我有一个最喜欢的电影列表。在表格单元格中,有一个用于从收藏夹列表中删除电影的按钮。所以我想用tableView.deleteRows 为它制作动画。但是,如果我从屏幕顶部删除一行,其他行会向上。这是正常的,但是当我从屏幕顶部删除行时,列表中已经显示的其他单元格没有更新 indexPath。我为 tableView.reloadData 分配了一个 asyncAfter 方法来解决问题,但我认为这可能会导致操作系统方面的崩溃。因为我在延迟后强制主线程重新加载数据。操作系统真的有问题吗?我该怎么办?

示例问题:

如果我删除索引为 0 的电影,所有电影都会向上播放。所以在删除之前,1 个索引电影应该有 0 个索引,但它没有。如果我试图删除一个新的 0 索引电影,它正在删除另一部电影。

Work example without tableView.reloadData()

这是我的代码 // 这是可行的,但我认为 asyncAfter 是个问题

cell.deleteButtonActionBlock = 
    FavouritesHandler.shared.deleteMovie(movie)
    self.tableView.deleteRows(at: [indexPath], with: .automatic)
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) 
        self.tableView.reloadData()
    

【问题讨论】:

你是在删除tableView.deleteRows之前的数据源数组中的项目吗? @Jithin 是 FavouritesHandler.shared.deleteMovie(movie) 从数组中删除电影 我猜你捕获索引路径的方式有问题。 @vadian this sn-p in tableView cellForRowAt indexPath 我不这么认为 我愿意,这正是问题所在。请看我的回答。 【参考方案1】:

如果可以删除、插入或移动单元格,您不得使用捕获的索引路径。

在自定义单元格中声明闭包

var deleteButtonActionBlock : ((UITableViewCell) -> Void)?

然后调用它

deleteButtonActionBlock?(self)

cellForRow中获取单元格的实际索引路径

cell.deleteButtonActionBlock =  aCell in
    let actualIndexPath = tableView.indexPath(for: aCell)!
    FavouritesHandler.shared.deleteMovie(movie)
    tableView.deleteRows(at: [actualIndexPath], with: .automatic)

没有(难看的)延迟,也不需要(毫无意义的)重新加载。

还请注意,我删除了 delete 行中的 self,因为 tableView 实例可用作方法参数。

【讨论】:

非常感谢。您能否解释一下为什么捕获的 indexPath 不能正常工作?这是我在 Swift 的第二周 :) 是的,capture 一词包含了解释。在您分配闭包的那一刻,索引路径被冻结并且不再改变。这会导致意外行为。 如果我没有弄错的话,使用 cellForRowAt indexPath 更新单元格时。但是通过使用闭包,我在使用 deleteButton 时通过了它。我真的很感激你。非常感谢您的帮助。 cellForRowdelete-/insertRows 之后不再被调用

以上是关于删除行后更新 indexPath 值的主要内容,如果未能解决你的问题,请参考以下文章

如何将 indexPath 数组拆分为单独的 indexPath 数组,每个数组的 indexPath 具有相同的 indexPath.section

升级项目后:删除现有行后 NSTableVIew 无法正确更新

Handsontable:删除行后更新渲染器

隐藏或删除行后如何更新 HTML 表中的行索引?

更新/插入/删除表中的行后触发的触发器有问题

SQLite):删除行后自动更新两个表中的索引