简体   繁体   English

UITableView 中的行不会立即删除

[英]Row in UITableView isn't deleted immediately

I'm using trailingSwipeActionsConfigurationForRowAt UITableView 's delegate method for handling when user swipe to delete certain cell (item).我正在使用trailingSwipeActionsConfigurationForRowAt UITableView的委托方法来处理用户滑动以删除某些单元格(项目)。

My UIContextualAction for delete event looks like this.我用于删除事件的UIContextualAction看起来像这样。 I first remove item from Realm database and then I delete row from my table view我首先从 Realm 数据库中删除项目,然后从表视图中删除行

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let deleteAction = UIContextualAction(style: .destructive, title: nil) { _,_,_ in
        Repository.shared.deleteItem(self.items![indexPath.row])
        tableView.deleteRows(at: [indexPath], with: .fade)
    }
    ...
}

But from some reason when I delete cell, it isn't deleted immediately and it returns to position between swipe.但是由于某种原因,当我删除单元格时,它不会立即删除,而是返回到滑动之间的位置。 Then when I scroll table view, cell disappeared like you can see in gif below:然后当我滚动表格视图时,单元格消失了,就像你在下面的 gif 中看到的一样:

在此处输入图片说明

I can "fix" this by reloading data of table view right after I remove certain item from database, but this is not what I want to, I want to use deleteRow(at:with:) because of animation.我可以通过在从数据库中删除某些项目后立即重新加载表视图的数据来“修复”这个问题,但这不是我想要的,我想使用deleteRow(at:with:)因为动画。


One my guess is, that it has something to do with deleting item from Realm database.我的一个猜测是,它与从 Realm 数据库中删除项目有关。

I'm deleting item using delete method我正在使用delete方法删除项目

func deleteItem(_ item: Item) {
    do {
        try realm.write {
            realm.delete(item)
        }
    } catch {
        print(error)
    }
}

then as data source array for my table view I'm using Realm's Results然后作为我的表视图的数据源数组,我正在使用 Realm 的Results

var items: Results<Item>?

Does anybody have any idea why this happens?有人知道为什么会这样吗? Thank you.谢谢你。

I was facing the exactly the issue you had.我正面临着你遇到的问题。 I'm using Realm too, and I also used Results<Item> as my tableView datasource.我也在使用 Realm,并且还使用了Results<Item>作为我的 tableView 数据源。

My implementation for swipe-to-delete-cell in tableView(_:, trailingSwipeActionsConfigurationForRowAt:) method is exactly same as yours: delete the swiped item in realm.write{} block, then call UITableView.deleteRows(at:with:) method to update the tableView.我在tableView(_:, trailingSwipeActionsConfigurationForRowAt:)方法中的滑动到删除单元的实现与你的完全相同:删除realm.write{}块中的滑动项,然后调用UITableView.deleteRows(at:with:)方法更新 tableView。 There's no need to update the datasource items as Realm Results<T> auto updates itself.无需更新数据源items因为 Realm Results<T>自动更新。

All is working well on iOS 13 and above, but when I tested it on iOS 12.4, iPhone 6 simulator, I had the same issue as you described in the question.一切都在 iOS 13 及更高版本上运行良好,但是当我在 iOS 12.4、iPhone 6 模拟器上对其进行测试时,我遇到了与您在问题中描述的问题相同的问题。

I figured out a solution while reading this article , it turned out that all you need to do is to call the completion handler provided in UIContextualAction.Handler after you have finished your updates, please refer to the code below:我在阅读这篇文章时想出了一个解决方案,原来你需要做的就是在你完成更新后调用 UIContextualAction.Handler 中提供的完成处理程序,请参考下面的代码:

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
    let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { _, _, completion in
        Repository.shared.deleteItem(self.items![indexPath.row])  // delete item from Realm
        tableView.deleteRows(at: [indexPath], with: .fade)  // update tableView
        completion(true) // notify the tableView that the swipe action has completed so now it can perform UI updates (this line is no longer needed on iOS 13+)
    }
    ...
}

This solved my problem, hope it works for you too.这解决了我的问题,希望它也适用于您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM