Ответ
Drag and Drop API для UICollectionView и UITableView — мощная системная фича, позволяющая пользователям интуитивно переупорядочивать контент внутри приложения и между приложениями.
Что позволяет делать:
- Перетаскивание ячеек внутри одной коллекции/таблицы.
- Перенос элементов между разными коллекциями/таблицами.
- Межпрограммный перенос данных между приложениями (например, изображение из Фото в ваше приложение).
- Поддержка мультитач-жестов для выбора и переноса нескольких элементов сразу.
Базовая реализация для UICollectionView:
-
Активация:
collectionView.dragInteractionEnabled = true collectionView.dragDelegate = self collectionView.dropDelegate = self -
Начало перетаскивания (Drag Delegate):
func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] { let item = dataModel.item(at: indexPath) let itemProvider = NSItemProvider(object: item.title as NSString) let dragItem = UIDragItem(itemProvider: itemProvider) dragItem.localObject = item // Контекст для внутреннего переноса return [dragItem] } -
Обработка "дропа" (Drop Delegate):
func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) { let destinationIndexPath = coordinator.destinationIndexPath ?? ... for item in coordinator.items { if let sourceIndexPath = item.sourceIndexPath { // ВНУТРЕННИЙ ПЕРЕНОС: перемещаем объект в модели данных collectionView.performBatchUpdates { let movedItem = dataModel.remove(at: sourceIndexPath) dataModel.insert(movedItem, at: destinationIndexPath) collectionView.moveItem(at: sourceIndexPath, to: destinationIndexPath) } } else { // МЕЖПРОГРАММНЫЙ ПЕРЕНОС: создаем новый объект из данных item.dragItem.itemProvider.loadObject(ofClass: NSString.self) { (data, error) in if let text = data as? String { DispatchQueue.main.async { self.dataModel.insert(Item(title: text), at: destinationIndexPath) collectionView.insertItems(at: [destinationIndexPath]) } } } } } }
Ключевые преимущества:
- Нативные жесты и анимации (поднятие ячейки, кастомный превью).
- Высокая производительность, интегрированная с системой.
- Универсальность: работает с любыми типами данных через
NSItemProvider.