Drag-and-Drop — як працює перетягування в мобільних додатках

Автор: IT Sectr Опубліковано: 2026-02-27 Час читання: 9 хв

Drag-and-Drop — інтерактивний жест перетягування візуального об’єкта по екрану пальцем. Жест складається з трьох фаз: захоплення (довге натискання або дотик), переміщення (рух пальця з об’єктом) і відпускання (скидання в цільову зону). Використовується для зміни порядку елементів, переміщення файлів між папками, організації інтерфейсу (drag to reorder, drag to resize). На iOS реалізується через UIDragInteraction, на Android — через DragEvent і startDragAndDrop.

Головне

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

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

Drag-and-Drop (DnD) — метод маніпуляції графічними елементами інтерфейсу, при якому користувач захоплює об’єкт пальцем або мишею, переміщує його в іншу позицію та відпускає. У мобільних інтерфейсах Drag-and-Drop зазвичай ініціюється довгим натисканням — користувач утримує елемент протягом 300–500 мс, після чого система перемикає інтерфейс у режим перетягування, і рух пальця переміщує об’єкт слідом.

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

Ключові концепції: сесія перетягування (drag session), елементи перетягування (drag items), попередній перегляд перетягування (drag preview — візуальний образ об’єкта), ціль скидання (drop target), пропозиція скидання (drop proposal — дія при скиданні: перемістити, скопіювати, зв’язати). Система керує сесією на рівні операційної системи, що дозволяє перетягувати об’єкти між різними додатками (наприклад, фото з Галереї в Нотатки).

Фази Drag-and-Drop

Drag-and-Drop поділяється на три послідовні фази. Фаза 1 — Захоплення (Початок перетягування): користувач ініціює жест (зазвичай довге натискання), система створює сесію перетягування, захоплює дані об’єкта та відображає попередній перегляд перетягування — напівпрозору копію елемента, що слідує за пальцем. У цій фазі система відхиляє інші жести (прокручування, виділення тексту) до завершення DnD.

Фаза 2 — Переміщення (Рух перетягування): палець рухається по екрану, попередній перегляд перетягування слідує за точкою дотику. Система безперервно визначає ціль скидання під пальцем і надсилає події drag-enter, drag-move та drag-exit. Ціль скидання може візуально реагувати: підсвічуватися, розширюватися або показувати лінію-вставку. Ця фаза триває від 0,5 до 10+ секунд залежно від складності завдання.

Фаза 3 — Відпускання (Скидання): палець відривається від екрану. Система завершує сесію перетягування та викликає зворотній виклик скидання у цільового елемента. Якщо ціль скидання відхиляє скидання (наприклад, перетягування файлу в папку без прав запису), попередній перегляд перетягування анімаційно повертається на вихідну позицію (анімація скасування). Якщо скидання прийнято, елемент зникає з вихідної позиції та з’являється в цільовій.

ФазаПодія iOSПодія AndroidВізуальний стан
ЗахопленняUIDragInteractionDelegate.dragSessionWillBeginView.OnLongClickListener → startDragAndDropПопередній перегляд з’являється під пальцем
ПереміщенняUIDropInteractionDelegate.dragSessionDidUpdateView.OnDragListener.onDrag (ACTION_DRAG_MOVED)Попередній перегляд рухається, ціль підсвічується
Відпускання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)

        // Попередній перегляд перетягування — зменшена копія елемента
        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. Тип операції впливає на візуальне відображення (значок + у кутку попереднього перегляду для копіювання, заборонний знак для 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 зі зменшеним попереднім переглядом
            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 — вбудований механізм, який автоматично обробляє довге натискання для захоплення, анімацію переміщення та утилітарні методи 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). Ціль скидання візуально підсвічується при наведенні, показуючи межі папки.

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

Розділи Springboard (iOS) — перетягування іконок додатків на головному екрані iOS. Довге натискання на іконку активує режим «трясіння» (іконки тремтять), після чого користувач може переміщувати іконки між сторінками та створювати папки. Це один із найскладніших UX-патернів DnD, оскільки вимагає одночасної обробки перетягування, анімації трясіння та групування в папки.

Рекомендації щодо UX для Drag-and-Drop

Візуальний зворотний зв’язок — критично важливий для Drag-and-Drop. Перетягуваний об’єкт повинен змінитися: зменшитися (iOS: масштаб 0,8–0,9), стати напівпрозорим (альфа 0,7–0,8) і піднятися над інтерфейсом з тінню (shadow offset). Ціль скидання повинна візуально реагувати на наведення: підсвічуватися, розширюватися або показувати межі. Без цих сигналів користувач не розуміє, куди можна скинути об’єкт.

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

РекомендаціяiOSAndroid
Захоплення жестомДовге натискання (стандарт)OnLongClickListener
Попередній переглядUIDragItem.previewProviderDragShadowBuilder
Тактильний зворотний зв’язокUIImpactFeedbackGeneratorHapticFeedbackConstants.LONG_PRESS
Анімація поверненняUIDragPreviewTargetViewPropertyAnimator
Пропозиція скиданняUIDropProposal (.move/.copy)ACTION_DROP + прапорці
Міжпрограмне DnDiOS 11+ Split View (iPad)Android 7.0+ Split Screen

Доступність: користувачі з моторними обмеженнями можуть не виконати жест перетягування. Надавайте альтернативи через кнопки «Перемістити вгору/вниз» для списків, контекстне меню «Перемістити в папку» для файлів. iOS VoiceOver підтримує ротор-дію «Перетягнути» для переміщення елементів. Android TalkBack надає кастомні дії через AccessibilityNodeInfo.addAction(). Nike Run Club і Apple Health використовують DnD для переупорядкування метрик на дашборді — з доступом через стандартні кнопки.

Часті запитання

Який жест використовується для ініціювання Drag-and-Drop?

Стандартний жест для початку Drag-and-Drop — довге натискання тривалістю 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 і прокручування вирішується через затримку захоплення. Якщо користувач починає рух пальця до завершення тайм-ауту довгого натискання (500 мс), жест інтерпретується як прокручування, а не як Drag-and-Drop. У iOS UIDragInteraction автоматично керує цим конфліктом через cancelsTouchesInView. В Android ItemTouchHelper використовує поріг — якщо рух перевищує поріг TouchSlop, довге натискання скасовується на користь прокручування.

Які дані можна передавати при перетягуванні?

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 дані упаковуються в універсальні формати: звичайний текст, HTML, RTF, UIImage/PNG.

Як анімувати повернення елемента при скасуванні Drag-and-Drop?

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

Підсумки

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

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

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