Возможно ли обменять 2 ячейки в UICollectionView, использующем UICollectionViewFlowLayout?
Скажем, у меня есть UICollectionView, используя UICollectionViewFlowLayout и следующий формат:
1 2 3
4 5 6
7 8 9
Я касаюсь ячейки 9 и перетаскиваю ее по ячейке 6, перемещая ячейку 9 туда, где находится ячейка 6, и ячейка 6, где ячейка 9:
1 2 3
4 5 9
7 8 6
Есть ли способ легко перемещать и анимировать ячейку 6, где находится ячейка 9, а также перемещать и анимировать ячейку 9, где находится ячейка 6? Или мне нужно подклассы UICollectionViewLayout? Если мне нужно подклассифицировать UICollectionViewLayout, как это сделать? Я попытался явно установить центры ячеек в
-(UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
но без успеха.
Ответы
Ответ 1
После большого удара головой, решение, которое я нашел, заключается в использовании moveItemAtIndexPath:toIndexPath
внутри performBatchUpdates:completion
. Согласно documentation для performBatchUpdates:completion
:
Вы можете использовать этот метод в тех случаях, когда вы хотите вставлять, удалять, перезагружать или перемещать ячейки вокруг представления коллекции в одной анимационной операции, в отличие от нескольких отдельных анимаций. Используйте заблокированный, переданный в параметре обновлений, чтобы указать все операции, которые вы хотите выполнить.
Итак, что я в основном делал, было
[self performBatchUpdates:^{
[self moveItemAtIndexPath:fromIp toIndexPath:toIp];
[self moveItemAtIndexPath:toIp toIndexPath:fromIp];
} completion:^(BOOL finished) {
// update data source here
// e.g [dataSource exchangeObjectAtIndex:fromIp.row withObjectAtIndex:toIp.row];
}];
Ответ 2
Вы пытались переупорядочить элементы напрямую с помощью moveItemAtIndexPath: toIndexPath:?
- убедитесь, что вы действительно переупорядочиваете базовую коллекцию моделей, чтобы изменения вступили в силу после полной перезагрузки в следующий раз.
Ответ 3
Быстрый код:
self.collectionView.performBatchUpdates({
self.collectionView.moveItem(at: selectedIndexPath, to: targetIndexPath)
self.collectionView.moveItem(at: targetIndexPath, to: selectedIndexPath)
}, completion: nil)