为了显示项目列表,我使用符合
UITableView
的 UITableViewDiffableDataSource
。我想对表行重新排序。为此,我使用了 tableView(_:canMoveRowAt:)
和 tableView(_:moveRowAt:to:)
。我在单元格上看不到重新排序按钮,并且两个委托功能均未触发。
但是当我将数据源更改为正常UITableViewDataSource
时,重新排序就起作用了。
import UIKit
import CoreData
typealias NewsItemDataSource = UITableViewDiffableDataSource<String, NSManagedObjectID>
typealias NewsItemSnapshot = NSDiffableDataSourceSnapshot<String, NSManagedObjectID>
class NewsItemViewController: UIViewController {
private var tableView: UITableView!
private var diffableDatasource: NewsItemDataSource!
override func viewDidLoad() {
super.viewDidLoad()
configureTableView()
performFetch()
}
private func performFetch() {
do {
try fetchedResultsController.performFetch()
} catch {
}
}
private func configureTableView() {
tableView = UITableView()
tableView.register(with: NewsItemTableViewCell.self) // refactored with extension
diffableDatasource = playsDiffableDataSource(tableView)
tableView.dataSource = diffableDatasource
tableView.isEditing = true
tableView.allowsSelection = false
tableView.delegate = self
}
func playsDiffableDataSource(_ tableView: UITableView) -> UITableViewDiffableDataSource<String, NSManagedObjectID> {
let diffableDatasource = UITableViewDiffableDataSource<String, NSManagedObjectID>(tableView: tableView) { (tableView, indexPath, objectID) -> UITableViewCell? in
guard let newsItem = try? CoreDataManager.shared.moc.existingObject(with: objectID) as? CDNewsItem else {
return UITableViewCell()
}
let cell: NewsItemTableViewCell = tableView.dequeueReusableCell(for: indexPath)
cell.configure(with: newsItem)
return cell
}
return diffableDatasource
}
private lazy var fetchedResultsController: NSFetchedResultsController<CDNewsItem> = {
// Create Fetch Request
let fetchRequest = CDNewsItem.fetchRequest()
// Configure Fetch Request
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "modificationDate", ascending: false)]
fetchRequest.fetchBatchSize = 30
// Create Fetched Results Controller
let moc = CoreDataManager.shared.moc
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: moc,
sectionNameKeyPath: nil,
cacheName: nil)
// Configure Fetched Results Controller
fetchedResultsController.delegate = self
return fetchedResultsController
}()
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
fetchedResultsController.fetchedObjects?.swapAt(sourceIndexPath.row, destinationIndexPath.row)
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCell.EditingStyle {
return .none
}
func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
return false
}
}
extension PlaysListViewController: NSFetchedResultsControllerDelegate {
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference) {
guard let diffableDatasource else { return }
diffableDatasource.apply(snapshot as NewsItemSnapshot, animatingDifferences: true)
}
}
也许不支持,UICollectionViewDiffableDataSource有一个重新排序处理程序结构https://developer.apple.com/documentation/uikit/uicollectionviewdiffabledatasourcereference/3600513-reorderinghandlers