Drag-and-Drop — суть, Drag and Drop в мобильных приложениях

Автор: IT Sectr Опубликовано: 2026-02-27 Время чтения: 9 мин

Drag-and-Drop — интерактивный жест перетаскивания визуального объекта по экрану с помощью пальца. Жест состоит из трёх фаз: захват (long press или касание), перемещение (движение пальца с объектом) и отпускание (сброс в целевой зоне). Используется для изменения порядка элементов, перемещения файлов между папками, организации интерфейса (drag to reorder, drag to resize). На iOS реализуется через UIDragInteraction, на Android — через DragEvent и startDragAndDrop.

Главное

  • Три фазы — Drag-and-Drop состоит из захвата, перемещения и отпускания объекта
  • UIDragInteraction — основной класс iOS для инициирования и обработки перетаскивания
  • startDragAndDrop — метод Android View для начала перетаскивания после захвата
  • Drag shadow — визуальная тень перетаскиваемого объекта, следует за пальцем
  • Drop target — зона сброса, которая подсвечивается при наведении перетаскиваемого объекта

Что такое Drag-and-Drop?

Drag-and-Drop (DnD, перетаскивание) — метод манипуляции графическими элементами интерфейса, при котором пользователь захватывает объект пальцем или мышью, перемещает его в другую позицию и отпускает. В мобильных интерфейсах Drag-and-Drop обычно инициируется длительным нажатием (Long Press) — пользователь удерживает элемент в течение 300–500 мс, после чего система переключает интерфейс в режим перетаскивания, и движение пальца перемещает объект следом.

Исторически Drag-and-Drop появился в десктопных интерфейсах (Xerox Star, 1981; Macintosh, 1984) как альтернатива командам копировать/вставить. На мобильных платформах полноценная поддержка появилась в iOS 11 (2017) с UIDragInteraction и в Android 7.0 (2016) с Multi-Window Drag-and-Drop. До этого перетаскивание в мобильных приложениях реализовывалось кастомными решениями через gesture recognizers.

Ключевые концепции: drag session (сессия перетаскивания), drag items (перетаскиваемые объекты), drag preview (визуальный образ объекта), drop target (зона сброса), drop proposal (действие при сбросе: переместить, копировать, связать). Система управляет сессией на уровне операционной системы, что позволяет перетаскивать объекты между разными приложениями (например, фото из Галереи в Заметки).

Фазы Drag-and-Drop

Drag-and-Drop разделяется на три последовательные фазы. Фаза 1 — захват (Drag Start): пользователь инициирует жест (обычно Long Press), система создаёт drag session, захватывает данные объекта и отображает drag preview — полупрозрачную копию элемента, следующую за пальцем. В этой фазе система отклоняет другие жесты (прокрутка, выделение текста) до завершения DnD.

Фаза 2 — перемещение (Drag Move): палец движется по экрану, drag preview следует за точкой касания. Система непрерывно определяет drop target под пальцем и отправляет события драг-энтири (drag enter), драг-мув (drag move) и драг-экзит (drag exit). Drop target может визуально реагировать: подсвечиваться, расширяться или показывать линию-вставку. Эта фаза длится от 0.5 до 10+ секунд в зависимости от сложности задачи.

Фаза 3 — отпускание (Drop): палец отрывается от экрана. Система завершает drag session и вызывает drop callback у целевого элемента. Если drop target отклоняет сброс (например, перетаскивание файла в папку без прав записи), drag preview анимированно возвращается на исходную позицию (cancel animation). Если сброс принят, элемент исчезает с исходной позиции и появляется в целевой.

ФазаСобытие iOSСобытие AndroidВизуальное состояние
ЗахватUIDragInteractionDelegate.dragSessionWillBeginView.OnLongClickListener → startDragAndDropDrag preview появляется под пальцем
ПеремещениеUIDropInteractionDelegate.dragSessionDidUpdateView.OnDragListener.onDrag (ACTION_DRAG_MOVED)Preview движется, target подсвечен
ОтпусканиеUIDropInteractionDelegate.performDropView.OnDragListener.onDrag (ACTION_DROP)Анимация сброса или возврата

Межприложное перетаскивание — функция, доступная на обеих платформах. iOS поддерживает Drag-and-Drop между приложениями в режиме Split View и Slide Over (iPad). Android поддерживает перетаскивание между приложениями в режиме Split Screen. Данные передаются через UIPasteConfiguration (iOS) или ClipData (Android). Разработчик указывает поддерживаемые типы данных (UTI для iOS, MIME для Android).

Drag-and-Drop в iOS: UIDragInteraction

UIDragInteraction — основной API iOS для перетаскивания, добавленный в iOS 11. Для включения перетаскивания из View добавьте UIDragInteraction с UIDragInteractionDelegate. Делегат определяет, какие элементы перетаскиваются, их внешний вид и поведение. Для приёма элементов используется UIDropInteraction с UIDropInteractionDelegate, который определяет, может ли View принять сброс и как обработать данные.

swift
// UIDragInteraction — перетаскивание элемента из коллекции
class DragViewController: UIViewController, UIDragInteractionDelegate {

    @IBOutlet var dragSourceView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        let dragInteraction = UIDragInteraction(delegate: self)
        dragSourceView.addInteraction(dragInteraction)
    }

    func dragInteraction(_ interaction: UIDragInteraction,
                          itemsForBeginning session: UIDragSession) -> [UIDragItem] {

        guard let data = Data(contentsOf: selectedFileURL) else { return [] }

        let itemProvider = NSItemProvider(object: data as NSData)
        let dragItem = UIDragItem(itemProvider: itemProvider)

        // Drag preview — уменьшенная копия элемента
        dragItem.previewProvider = {
            let previewView = UIImageView(image: thumbnailImage)
            previewView.alpha = 0.8
            return UIDragPreview(view: previewView)
        }
        return [dragItem]
    }
}

UIDropInteractionDelegate — зеркальный интерфейс для приёма сброса. Метод canHandle(_:) проверяет, поддерживается ли тип данных. sessionDidUpdate(_:) визуально обновляет состояние (подсветка, линия-вставка). performDrop(_:) выполняет финальную обработку данных. iOS автоматически вызывает UIDropProposal с типом операции: .move (переместить), .copy (копировать), .forbidden (запрещено). Тип операции влияет на визуальное отображение (значок + в углу preview для копирования, запрещающий знак для forbidden).

Drag-and-Drop в Android: startDragAndDrop

View.startDragAndDrop() — метод Android SDK для начала перетаскивания, доступный с API 24 (Android 7.0). Вызывается после захвата элемента (обычно в onLongClick). Параметры: ClipData (данные), DragShadowBuilder (визуальная тень), Object myLocalState (локальное состояние), flags. DragShadowBuilder создаёт Bitmap, который следует за пальцем. Система автоматически управляет анимацией и сенсорными событиями во время перетаскивания.

kotlin
// Drag-and-Drop элемента RecyclerView с переупорядочиванием
class ReorderAdapter(private val items: MutableList<String>) :
    RecyclerView.Adapter<ReorderAdapter.ViewHolder>() {

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.itemView.setOnLongClickListener {
            // Создаём ClipData для передачи данных
            val clipData = ClipData.newPlainText("item", items[position])

            // Кастомный DragShadowBuilder с уменьшенным preview
            val shadowBuilder = object : View.DragShadowBuilder(holder.itemView) {
                override fun onProvideShadowMetrics(shadowSize: Point, shadowTouchPoint: Point) {
                    shadowSize.set(itemView.width, itemView.height / 2)
                }
            }

            holder.itemView.startDragAndDrop(clipData, shadowBuilder, position, 0)
            true
        }
    }
}

Приём сброса в Android реализуется через View.setOnDragListener(). Слушатель получает события ACTION_DRAG_STARTED, ACTION_DRAG_ENTERED, ACTION_DRAG_LOCATION, ACTION_DRAG_EXITED, ACTION_DROP, ACTION_DRAG_ENDED. В событии ACTION_DROP извлекаются данные из ClipData и выполняется целевое действие. Для RecyclerView с переупорядочиванием рекомендуется ItemTouchHelper.SimpleCallback — встроенный механизм, который автоматически обрабатывает Long Press для захвата, анимацию перемещения элементов и утилитарные методы onMove/onSwiped.

Сценарии применения Drag-and-Drop

Переупорядочивание списков (drag to reorder) — самый частый сценарий DnD: пользователь перетаскивает элементы списка для изменения их порядка. Примеры: перестановка контактов в избранном, сортировка задач в трекерах (Trello, Todoist), изменение порядка треков в плейлисте (Spotify, Apple Music). Реализуется через ItemTouchHelper в Android или UILongPressGestureRecognizer + перестановка ячеек в iOS.

Файловые менеджеры — Drag-and-Drop для копирования и перемещения файлов между папками. iOS Files App, Android Files by Google, Dropbox — все поддерживают DnD. Перетаскивание файла на папку перемещает его внутрь (move), перетаскивание с зажатой клавишей Option/Ctrl — копирует (copy). Drop target визуально подсвечивается при наведении, показывая границы папки.

Канбан-доски — Trello, Jira, Notion используют Drag-and-Drop для перемещения карточек между колонками (To Do → In Progress → Done). При перетаскивании карточка открепляется от исходной колонки, следует за пальцем, и при пересечении границы другой колонки вставляется с анимацией. iOS 11+ поддерживает UIDragPreview с параллакс-эффектом, где preview слегка отклоняется от точки касания, создавая глубину.

Разделы Springboard (iOS) — перетаскивание иконок приложений на домашнем экране iOS. Долгое нажатие на иконку активирует режим "jiggling" (иконки трясутся), после чего пользователь может перемещать иконки между страницами и создавать папки. Это один из самых сложных UX-паттернов DnD, так как требует одновременной обработки перетаскивания, анимации тряски и группировки в папки.

Рекомендации по UX для Drag-and-Drop

Визуальная обратная связь — критически важна для Drag-and-Drop. Перетаскиваемый объект должен измениться: уменьшиться (iOS: scale 0.8–0.9), стать полупрозрачным (alpha 0.7–0.8) и подняться над интерфейсом с тенью (shadow offset). Drop target должен визуально реагировать на наведение: подсвечиваться (highlight), расширяться (expand) или показывать границы (border). Без этих сигналов пользователь не понимает, куда можно сбросить объект.

Анимация возврата (drag cancel) — если пользователь отпускает элемент вне зоны сброса или над невалидной зоной, объект должен анимированно вернуться на исходную позицию. iOS UIDragInteractionDelegate предоставляет dragInteraction(_:sessionDidMove:) для отслеживания и dragInteraction(_:session:willEndWith:) для анимации возврата. Android View.setOnDragListener получает ACTION_DRAG_ENDED, где можно запустить анимацию возврата через ValueAnimator или ObjectAnimator.

РекомендацияiOSAndroid
Захват жестомLong Press (default)OnLongClickListener
Drag previewUIDragItem.previewProviderDragShadowBuilder
Тактильная обратная связьUIImpactFeedbackGeneratorHapticFeedbackConstants.LONG_PRESS
Анимация возвратаUIDragPreviewTargetViewPropertyAnimator
Drop proposalUIDropProposal (.move/.copy)ACTION_DROP + флаги
Межприкладное DnDiOS 11+ Split View (iPad)Android 7.0+ Split Screen

Доступность: пользователи с моторными ограничениями могут не выполнить жест перетаскивания. Предоставляйте альтернативы через кнопки "Move Up/Down" для списков, контекстное меню "Move to Folder" для файлов. iOS VoiceOver поддерживает ротор-действие "Drag" для перемещения элементов. Android TalkBack предоставляет кастомные действия через AccessibilityNodeInfo.addAction(). Nike Run Club и Apple Health используют DnD для переупорядочивания метрик на дашборде — с доступом через стандартные кнопки.

Часто задаваемые вопросы

Какой жест используется для инициализации Drag-and-Drop?

Стандартный жест для начала Drag-and-Drop — Long Press (долгое нажатие) длительностью 300–500 мс. iOS использует встроенный механизм UIDragInteraction, который автоматически конвертирует продолжительное касание в захват. Android требует явного вызова startDragAndDrop() в коллбэке OnLongClickListener. В некоторых случаях (например, в играх) DnD может начинаться с обычного касания без задержки.

Можно ли перетаскивать объекты между разными приложениями?

Да, межприкладной Drag-and-Drop поддерживается на iOS 11+ (iPad) и Android 7.0+. На iPad перетаскивание работает в режиме Split View и Slide Over — пользователь может взять текст из Safari и перенести в Заметки. В Android DnD между приложениями работает в Split Screen. Данные передаются через UIPasteConfiguration (iOS) или ClipData (Android) с указанием поддерживаемых типов (UTI, MIME).

Как предотвратить конфликт Drag-and-Drop с прокруткой?

Конфликт DnD и Scroll решается через задержку захвата. Если пользователь начинает движение пальца до истечения таймаута Long Press (500 мс), жест интерпретируется как прокрутка, а не как Drag-and-Drop. В iOS UIDragInteraction автоматически управляет этим конфликтом через cancelsTouchesInView. В Android ItemTouchHelper использует threshold — если движение превышает порог TouchSlop, Long Press отменяется в пользу прокрутки.

Какие данные можно передавать при перетаскивании?

Drag-and-Drop поддерживает любые типы данных: текст, изображения, файлы, URL, кастомные объекты. iOS использует NSItemProvider с UTI-типами (public.text, public.image, public.file-url). Android — ClipData с MIME-типами (text/plain, image/png, application/octet-stream). Для кастомных данных создаётся ClipData.Item с Intent. При межприкладном DnD данные упаковываются в универсальные форматы: plain text, HTML, RTF, UIImage/PNG.

Как анимировать возврат элемента при отмене Drag-and-Drop?

В iOS анимация возврата обрабатывается через UIDragPreviewTarget — финальная позиция, к которой анимированно возвращается preview. В Android используйте ViewPropertyAnimator с translateX/translateY для возврата элемента в исходную позицию. Время анимации — 200–300 мс с кривой easing (EaseOut). UIKit автоматически добавляет UIDragPreview с параллакс-эффектом, который плавно возвращается при отмене жеста.

Итоги

  • Drag-and-Drop — метод перетаскивания объектов с тремя фазами: захват, перемещение, отпускание
  • Инициализация — обычно через Long Press (300–500 мс) для различения с прокруткой
  • iOS API — UIDragInteraction (источник) + UIDropInteraction (приёмник)
  • Android API — View.startDragAndDrop() (источник) + View.setOnDragListener (приёмник)
  • ItemTouchHelper — готовое решение Android для переупорядочивания в RecyclerView
  • Drag preview — визуальная тень объекта, следующая за пальцем с полупрозрачностью
  • Анимация возврата — обязательна при сбросе вне валидной зоны для понятного UX

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также