我有一个UIViewController
,其中包含一个UICollectionView
和一个UITableView
。这两个视图分别使用UICollectionViewDiffableDataSource
和UITableViewDiffableDataSource
。
在表中,我尝试为删除操作设置swipe功能。对于常规数据源来说,这是一个非常简单的任务,但我无法让它与diffable数据源一起工作。
我尝试为UITableViewDiffableDataSource
创建一个自定义类,但我甚至无法编译代码,因为我尝试从控制器访问该属性。(我需要访问存储模型的属性,以便不仅删除行,还删除数据。)使用UITableViewDelegate
和tableView(leadingSwipeActionsConfigurationForRowAt:)
确实编译了,我可以滑动,但应用程序崩溃并出现错误:* 作为UITableView的数据源时,必须通过UITableViewDiffableDataSource API更新UITableView *。
我该怎么做?有没有适合做这种工作的最佳实践?
编辑1:
根据评论中的要求,我提供了一些代码,用于最近的实现尝试。
在UIViewController
中(这是一个很长的实现,所以我省略了大部分):
class ViewController: UIViewController, ItemsTableViewDiffableDataSourceDelegate {
@IBOutlet var tableView: UITableView!
var items = [Item]()
var tableViewDataSource: ItemsTableViewDiffableDataSource!
var itemsSnapshot: NSDiffableDataSourceSnapshot<String, Item> {
var snapshot = NSDiffableDataSourceSnapshot<String, Item>()
snapshot.appendSections(["Items"])
snapshot.appendItems(items)
return snapshot
}
func configureTableViewDataSource() {
// A working implementation
}
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .destructive, title: "Delete") { action, view, handler in
self.items.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .fade)
}
deleteAction.backgroundColor = .red
let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
configuration.performsFirstActionWithFullSwipe = false
return configuration
}
}
在UITableViewDiffableDataSource
中(完整实现):
@MainActor
class ItemsTableViewDiffableDataSource: UITableViewDiffableDataSource<String, Item> {
}
protocol ItemsTableViewDiffableDataSourceDelegate: AnyObject {
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?
}
最初,我在数据源类中定义了tableView(leadingSwipeActionsConfigurationForRowAt:)
方法,但我无法访问items
属性,所以我尝试使用一个协议。无论哪种方式,实现都不起作用-我无法滑动,更不用说删除项和表行了。
编辑二:
我猜真实的的问题是--如何用我的tableView
注册tableView(leadingSwipeActionsConfigurationForRowAt:)
方法。
1条答案
按热度按时间t3psigkw1#
事实证明,实现相当简单,在我的例子中不需要定制的
UITableViewDiffableDataSource
类,整个实现都进入了视图控制器。请记住将视图控制器设置为表视图的委托,这可以在
viewDidLoad()
中实现(感谢HangarRash在注解中的提示)。我在尝试这种方法时的第一个错误是,我仍然试图通过直接操作表视图来更新数据。
***由于未捕获的异常“NSInternalInconsistencyException”,正在终止应用程序,原因:'当UITableView充当UITableView的数据源时,必须通过UITableViewDiffableDataSource API更新UITableView:请不要直接在UITableView上调用变体API。
请改为调用
self.tableViewDataSource.apply(self.itemsSnapshot, animatingDifferences: true)
。