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("елемент", 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 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също