Как реализовать операцию перетаскивания в перетаскивании 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способ заставить это работать правильно? Если заполнитель - это правильная идея, как мне использовать его в этой ситуации?

0 ответов