UICollectionViewDropDelegate неправильный путь индекса назначения в `dropSessionDidUpdate` - PullRequest
1 голос
/ 21 сентября 2019

Я пытаюсь реализовать Drag & Drop в этом длинном узком виде коллекции: UICollectionView

Он имеет горизонтальную компоновку с ячейками и сечениями разного размера.

Взаимодействие с перетаскиванием работает хорошо, но я заметил проблему в UICollectionViewDropDelegate :

func collectionView(
    _ collectionView: UICollectionView,
    dropSessionDidUpdate session: UIDropSession,
    withDestinationIndexPath destinationIndexPath: IndexPath?)
    -> UICollectionViewDropProposal {

    if let destination = destinationIndexPath {
        print(destination) // Prints WRONG index path!!!
        return UICollectionViewDropProposal(
            operation: .move, intent: .insertAtDestinationIndexPath
        )
    }

    return UICollectionViewDropProposal(
        operation: .cancel, intent: .unspecified
    )
}

Неправильный путь индекса назначения передан в collectionView(_:dropSessionDidUpdate:withDestinationIndexPath:).
Из-зачто я не могу правильно определить раздел и решить, есть ли в нем доступ.

1 Ответ

1 голос
/ 21 сентября 2019

Итак, это ошибка UIKit.Правильный путь индекса назначения может быть рассчитан следующим образом:

func collectionView(
    _ collectionView: UICollectionView,
    dropSessionDidUpdate session: UIDropSession,
    withDestinationIndexPath destinationIndexPath: IndexPath?)
    -> UICollectionViewDropProposal {

    // Calculating location in view
    let location = session.location(in: collectionView)
    var correctDestination: IndexPath?

    // Calculate index inside performUsingPresentationValues
    collectionView.performUsingPresentationValues {
        correctDestination = collectionView.indexPathForItem(at: location)
    }

    guard let destination = correctDestination else {
        return UICollectionViewDropProposal(
            operation: .cancel, intent: .unspecified
        )
    }

    // check destination 
    // ...
}

Чтобы исправить эту ошибку, сначала я попытался использовать комбинацию location(in:) и indexPathForItem(at:).Полученный индексный путь был равен destinationIndexPath, предоставленному методом делегата.Почему?Мое внимание привлек UIDataSourceTranslating .Это протокол, позволяющий коллекциям и табличным представлениям показывать ячейки-заполнители для перетаскивания без изменения фактического источника данных.И когда взаимодействие перетаскивания заканчивается, заполнители легко удаляются.Итак, я сделал предположение, что

  1. destinationIndexPath рассчитывается с помощью indexPathForItem(at:)
  2. Он игнорирует заполнители, созданные UIDataSourceTranslating, что является ошибкой

Затем я попытался обернуть indexPathForItem(at:) в performUsingPresentationValues(_:), и полученный путь индекса был правильным!

...