Вам необходимо вызвать endInteractiveMovement in perfomBatchUpdates .
Но всякий раз, когда срабатывает endInteractiveMovement , вызывается cellForRow . Таким образом, ячейка будет обновлена, и будет добавлена новая ячейка (проверка со случайным расширением цвета). Для этого вам нужно сохранить selectedCell в переменной. И вернуть эту ячейку при вызове endInteractiveMovement .
Объявление currentCell в ViewController
var isEnded: Bool = true
var currentCell: UICollectionViewCell? = nil
Сохранить выбранную ячейку в переменной, когда начался жест, и вызвать endInteractiveMovement in executeBatchUpdates .
Итак, ваша функция handleLongGesture выглядит следующим образом:
//Selectors
@objc func handleLongGesture(gesture: UILongPressGestureRecognizer) {
switch(gesture.state) {
case .began:
guard let selectedIndexPath = collectionView.indexPathForItem(at: gesture.location(in: collectionView)) else {
break
}
isEnded = false
//store selected cell in currentCell variable
currentCell = collectionView.cellForItem(at: selectedIndexPath)
collectionView.beginInteractiveMovementForItem(at: selectedIndexPath)
case .changed:
collectionView.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view!))
case .ended:
isEnded = true
collectionView.performBatchUpdates({
self.collectionView.endInteractiveMovement()
}) { (result) in
self.currentCell = nil
}
default:
isEnded = true
collectionView.cancelInteractiveMovement()
}
}
Также необходимо изменить cellForRow
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if currentCell != nil && isEnded {
return currentCell!
} else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath)
cell.backgroundColor = .random
return cell
}
}
TIP
Используйте произвольное расширение цвета для лучшего тестирования
extension UIColor {
public class var random: UIColor {
return UIColor(red: CGFloat(drand48()), green: CGFloat(drand48()), blue: CGFloat(drand48()), alpha: 1.0)
}
}
EDIT
Если у вас есть несколько разделов.
Давайте возьмем массив массива
var data: [[String]] = [["1","2"],
["1","2","3","4","5","6","7"],
["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15"]]
Тогда вам нужно сохранить данные при переупорядочении
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
print("\(sourceIndexPath) -> \(destinationIndexPath)")
let movedItem = data[sourceIndexPath.section][sourceIndexPath.item]
data[sourceIndexPath.section].remove(at: sourceIndexPath.item)
data[destinationIndexPath.section].insert(movedItem, at: destinationIndexPath.item)
}