无法在 iOS 13 中使用可区分数据源通过 tableview 滑动删除

Unable to swipe to delete with tableview using diffable data source in iOS 13

我正在更新 UITableViewController 以使用新的 UITableViewDiffableDataSource,除了滑动删除之外,我的一切正常。

这是我如何使用滑动删除的示例

func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {

   let lockedAction = UIContextualAction(style: .normal, title: "TEST") { (_, _, completion) in
       print("tapped....")
       completion(true)
   }

    return UISwipeActionsConfiguration(actions: [lockedAction])
}

但这在具有 UITableViewDiffableDataSource

UITableViewController 中不起作用

没有滑动,也从不调用方法中的断点

我认为这是一个测试版错误,但我更新到 Xcode 11 GM 并且发生了同样的事情。

感谢任何建议

您应该将 UITableViewDiffableDataSource 和 return true 子类化为您要在

中启用此功能的行
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool

docs for tableView(_:canEditRowAt:) 说的是真的:

The method permits the data source to exclude individual rows from being treated as editable. Editable rows display the insertion or deletion control in their cells. If this method is not implemented, all rows are assumed to be editable

但是 UITableViewDiffableDataSource 确实 实现了那个方法,它似乎默认 return false (虽然我找不到那个记录在任何地方)。

事实上,WWDC 2019 会议 215 和 220 中的 sample code 实现了一个自定义 UITableViewDiffableDataSource 子类,如下所示:

class DataSource: UITableViewDiffableDataSource<SectionType, ItemType> {
    // ... 
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }
    // ...
}

如果您的自定义 UITableViewDiffableDataSource class 继承自另一个自定义 UITableViewDiffableDataSource class,您需要在 parent 中实现 trailingSwipeActionsConfigurationForRowAt 方法] class 使用 default 实现,然后在 child class 中覆盖它以便调用:

Parent class:

class ParentDataSource: UITableViewDiffableDataSource<SectionType, ItemType> {
    // ... 

    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        return nil
    }
    // ...
}

Child class:

class ChildDataSource: ParentDataSource {
    // ... 
    override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let lockedAction = UIContextualAction(style: .normal, title: "TEST") { (_, _, completion) in
            print("tapped....")
            completion(true)
        }

        return UISwipeActionsConfiguration(actions: [lockedAction])
    }
    // ...
}

我遇到了同样的问题,这是唯一对我有用的解决方案。