NSFetchedResultsController + UICollectionViewDiffableDataSource + CoreData - Как использовать весь объект? - PullRequest
1 голос
/ 21 октября 2019

Я пытаюсь использовать некоторые из новых классов сравнения, встроенных в iOS 13, вместе с Core Data. Проблема, с которой я сталкиваюсь, заключается в том, что controllerdidChangeContentWith не работает должным образом. Он передает мне ссылку на снимок, которая является ссылкой на NSDiffableDataSourceSnapshot<Section, NSManagedObjectID>, что означает, что я получаю список разделов / идентификаторов объектов, которые изменились.

Эта часть прекрасно работает. Но проблема возникает, когда вы переходите к разнице в представлении коллекции. В видео WWDC они радостно называют dataSource.apply(snapshot, animatingDifferences: true), и все работает волшебным образом, но это не так в реальном API.

В своей первоначальной попытке я попытался это сделать:

resolvedSnapshot.appendItems(snapshot.itemIdentifiersInSection(withIdentifier: section).map {
     controller.managedObjectContext.object(with: $0 as! NSManagedObjectID) as! Activity
}, toSection: .all)

И это работает для заполнения ячеек, но если данные меняются в ячейке (т. Е. Название ячейки) конкретной ячейкиникогда не перезагружается. Я взглянул на снимок, и, похоже, проблема в том, что у меня есть ссылки на эти объекты активности, поэтому они оба обновляются одновременно (имеется в виду, что действие в старом снимке эквивалентно действию в новом снимке, поэтомухэши равны.)

Мое текущее решение использует структуру, которая содержит все мои переменные класса Activity, но отключает ее от CoreData. Таким образом, мой источник данных стал: var dataSource: UICollectionViewDiffableDataSource<Section, ActivityStruct> Таким образом, снимок фактически получает два разных значения, потому что он имеет два разных объекта для сравнения. Это работает, но кажется, что это не так элегантно, так мы должны были это использовать? Или это сейчас просто в сломанном состоянии? Видео WWDC, кажется, подразумевает, что это не должно требовать всего этого дополнительного шаблона.

1 Ответ

1 голос
/ 05 ноября 2019

Я столкнулся с той же проблемой, и я думаю, что я понял, что работает:

Есть два класса: UICollectionViewDiffableDataSource и UICollectionViewDiffableDataSourceReference

Из того, что я могу сказать, когда выЕсли использовать первое, вы становитесь владельцем «Истины», поэтому вы создаете объект, который действует как источник данных. Когда вы используете второй (ссылка на источник данных), вы переносите «Источник истины» на другой источник данных (в данном случае CoreData).

Вы можете создать экземпляр ...DataSourceReference по существу так же, какa ...DataSource:

dataSourceReference = UICollectionViewDiffableDataSourceReference(collectionView: collectionView, cellProvider: { (collectionView, indexPath, object) -> UICollectionViewCell? in
    let identifier = <#cell identifier#>
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath)

    <#cell configuration#>

    return cell
})

А потом, когда вы реализуете NSFetchedResultsControllerDelegate, вы можете использовать следующий метод:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshot: NSDiffableDataSourceSnapshotReference)
{
    dataSourceReference.applySnapshot(snapshot, animatingDifferences: true)
}

Я смотрел видео WWDC какну и не видел, на что ссылаются. Пришлось сделать несколько ошибок, чтобы попасть сюда. Я надеюсь, что это работает для вас!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...