Переупорядочение ячеек с UICollectionViewDiffableDataSource и NSFetchedResultsController - PullRequest
0 голосов
/ 20 сентября 2019

Я использую UICollectionViewDiffableDataSource и NSFetchedResultsController для заполнения моего UICollectionView внутри моего UIViewController.

Чтобы добавить возможность переупорядочения ячеек, я добавил UILongPressGestureRecognizer и подклассы UICollectionViewDiffableDataSource, чтобы использовать методы canMoveItemAt: и moveItemAt:.

При переупорядочении ячейки следующеепроисходят вещи:

  1. moveItemAt: вызывается, и я обновляю свойство позиции объектов и сохраняю MOC
  2. controllerDidChangeContent: из NSFetchedResultsControllerDelegate вызывается, и я создаю новый снимокот текущего fetchedObjects и применить его.

Когда я применяю dataSource?.apply(snapshot, animatingDifferences: true), ячейки немедленно переключаются назад.Если я установлю animatingDifferences: false, это будет работать, но все ячейки будут перезагружены заметно .

Есть ли здесь наилучшая практика, как осуществить переупорядочение ячеек на UICollectionViewDiffableDataSource и NSFetchedResultsController?

Вот мои упомянутые методы:

// ViewController 
func createSnapshot(animated: Bool = true) {
    var snapshot = NSDiffableDataSourceSnapshot<Int, Favorite>()
    snapshot.appendSections([0])
    snapshot.appendItems(provider.fetchedResultsController.fetchedObjects ?? [])
    dataSource?.apply(snapshot, animatingDifferences: animated)
}

// NSFetchedResultsControllerDelegate
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    createSnapshot(animated: false)
}

// Subclassed UICollectionViewDiffableDataSource
override func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
    provider.moveFavorite(from: sourceIndexPath.row, to: destinationIndexPath.row)
}

// Actual cell moving in a provider class
public func moveFavorite(from source: Int, to destination: Int) {
    guard let favorites = fetchedResultsController.fetchedObjects else { return }
    if source < destination {
        let partialObjects = favorites.filter({ $0.position <= destination && $0.position >= source })

        for object in partialObjects {
            object.position -= 1
        }

        let movedFavorite = partialObjects.first
        movedFavorite?.position = Int64(destination)
    }
    else {
        let partialObjects = favorites.filter({ $0.position >= destination && $0.position <= source })

        for object in partialObjects {
            object.position += 1
        }

        let movedFavorite = partialObjects.last
        movedFavorite?.position = Int64(destination)
    }
    do {
        try coreDataHandler.mainContext.save()
    } catch let error as NSError {
        print(error.localizedDescription)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...