Как реализовать операцию перетаскивания в перетаскивании UICollectionView с использованием асинхронного источника данных и регистрации ячейки?
у меня есть
UICollectionView
привязан к
UICollectionViewDiffableDataSource
, и я создаю и применяю снимки к источнику данных в фоновой последовательной очереди и генерирую ячейки с помощью UICollectionViewCellRegistration
. Я работаю над поддержкой переупорядочения содержимого представления коллекции с помощью перетаскивания, и у меня проблемы с тем, что делать в
collectionView:performDropWithCoordinator:
так что анимация изменения порядка выглядит правильно.
Обычно я бы сделал что-то вроде этого:
-(void)collectionView:(UICollectionView *)collectionView performDropWithCoordinator:(id<UICollectionViewDropCoordinator>)coordinator
{
NSIndexPath *sourcePath = (NSIndexPath *)coordinator.items.firstObject.dragItem.localObject;
NSInteger fromIndex = sourcePath.item;
NSInteger toIndex = coordinator.destinationIndexPath.item;
NSNumber *fromItem = [self.datasource itemIdentifierForIndexPath:sourcePath];
NSNumber *toItem = [self.datasource itemIdentifierForIndexPath:coordinator.destinationIndexPath];
//Do the move in the data model
[MyModel moveItemFrom:fromIndex to:toIndex];
//Do the move in the datasource. This is the data source equivalent of:
//[collectionView moveItemAtIndexPath:sourcePath toIndexPath:coordinator.destinationIndexPath];
NSDiffableDataSourceSnapshot *snap = self.datasource.snapshot;
if (toIndex < fromIndex)
[snap moveItemWithIdentifier:fromItem beforeItemWithIdentifier:toItem];
else
[snap moveItemWithIdentifier:fromItem afterItemWithIdentifier:toItem];
[self.dataSource applySnapshot:snap animated:YES];
//Drop the item
[coordinator dropItem:coordinator.items.firstObject.dragItem toItemAtIndexPath:coordinator.destinationIndexPath];
}
Но поскольку обновления моих источников данных происходят в фоновой очереди, я должен как минимум выполнить создание снимка и приложение асинхронно, и я хотел бы также внести в него фактическую модификацию модели данных, чтобы избежать зависаний. И мне нужно позвонить
dropItem
на координаторе в основной очереди в этом методе. Это приводит к странной анимации, когда выпавший предмет на мгновение исчезает (когда
drop
вызывается), а затем снова появляется (когда источник данных обновляется в фоновой очереди).
На данный момент лучшая идея - использовать UICollectionViewDropPlaceholder
чтобы удерживать место в представлении коллекции до обновления источника данных. Но для создания заполнителя мне нужен идентификатор повторного использования ячейки (документация по методу инициализации), а у меня его нет, потому что я создаю свои ячейки, используя регистрацию ячеек.
Итак, мой вопрос: что мне делать в
performDrop
способ заставить это работать правильно? Если заполнитель - это правильная идея, как мне использовать его в этой ситуации?