Приведи пример мощной нативной фичи iOS для взаимодействия с пользователем.

«Приведи пример мощной нативной фичи iOS для взаимодействия с пользователем.» — вопрос из категории Other, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Drag and Drop API для UICollectionView и UITableView — мощная системная фича, позволяющая пользователям интуитивно переупорядочивать контент внутри приложения и между приложениями.

Что позволяет делать:

  • Перетаскивание ячеек внутри одной коллекции/таблицы.
  • Перенос элементов между разными коллекциями/таблицами.
  • Межпрограммный перенос данных между приложениями (например, изображение из Фото в ваше приложение).
  • Поддержка мультитач-жестов для выбора и переноса нескольких элементов сразу.

Базовая реализация для UICollectionView:

  1. Активация:

    collectionView.dragInteractionEnabled = true
    collectionView.dragDelegate = self
    collectionView.dropDelegate = self
  2. Начало перетаскивания (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]
    }
  3. Обработка "дропа" (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.