У меня есть ячейки в виде коллекции.Некоторые из этих клеток могут быть больше, чем другие.Я рассчитываю размер ячеек в collectionView(_:layout:sizeForItemAt:)
.
. Чтобы включить перетаскивание в представлении коллекции, я переопределил collectionView(_:canMoveItemAt:)
и collectionView(_:moveItemAt:to:)
.Пока все хорошо, ячейки можно перетаскивать.
У меня есть функция для обмена элементами в dataSource:
func moveCell<T>(from source: IndexPath, to destination: IndexPath, in dataSource: inout [[T]]) {
let itemToMove = dataSource[source.section][source.row]
dataSource[source.section].remove(at: source.row)
dataSource[destination.section].insert(itemToMove, at: destination.row)
}
Изначально я реализовал функцию moveCell(from:to:in:)
вcollectionView(_:moveItemAt:to:)
метод. Однако с этим решением размер клеток был перепутан.Также, если я пытаюсь перетащить ячейку в другой раздел, индекс выходит за пределы диапазона в методе collectionView(_:layout:sizeForItemAt:)
.
Поэтому я попытался поместить функцию moveCell(from:to:in:)
в collectionView(_:targetIndexPathForMoveFromItemAt:toProposedIndexPath:)
и ушелметод collectionView(_:moveItemAt:to:)
пустой.(Это не оптимально, но все, что требуется ...) Так что в этом сценарии размер ячейки является правильным для ячейки, которую я перетаскиваю, и всех других ячеек. Однако, если я перетаскиваю последнюю ячейку первого раздела или первую ячейку последнего раздела в другой раздел, я получаю индекс ошибки диапазона в методе collectionView(_:layout:sizeForItemAt:)
.
Вот мой источник данных:
var data: [[String]] = [
["Rabbit", "Turtle", "Unecessarily long title for getting a second line maybe hopefully."],
["Fish"]
]
Расчет размера:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = collectionView.contentSize.width
let height: CGFloat = data[indexPath.section][indexPath.row].height(with: width, size: 17) + 20
return CGSize(width: width, height: height)
}
В первом описанном мною решении я реализовал перемещение следующим образом:
override func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
moveCell(from: sourceIndexPath, to: destinationIndexPath, in: &data)
}
Во втором решении, которое я описал, я реализовал перемещение следующим образом:
override func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
// moveCell(from: sourceIndexPath, to: destinationIndexPath, in: &data)
}
override func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath {
moveCell(from: originalIndexPath, to: proposedIndexPath, in: &data)
return proposedIndexPath
}
Вот мой полный код UICollectionViewController для моего первого решения.