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 preview — полупрозирну копију елемента која прати прст. У овој фази, систем одбацује друге гестове (скроловање, селекција текста) до завршетка DnD.

Фаза 2 — помијерање (Drag Move): прст се креће по екрану, drag preview прати тачку додира. Систем непрекидно одређује drop target испод прста и шаље догађаје drag enter, drag move и drag exit. Drop target може визуелно да реагује: да се упали, прошири или прикаже линију уметања. Ова фаза траје од 0.5 до 10+ секунди у зависности од сложености задатка.

Фаза 3 — отпуштање (Drop): прст се подиже са екрана. Систем завршава сесију превлачења и позива 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 — главни iOS API за превлачење, додат у 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 се визуелно пали при налажењу, показујући границе фолдера.

Kanban табле — 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 (подразумевано)OnLongClickListener
Drag previewUIDragItem.previewProviderDragShadowBuilder
Тактилна повратна спрегаUIImpactFeedbackGeneratorHapticFeedbackConstants.LONG_PRESS
Анимација повраткаUIDragPreviewTargetViewPropertyAnimator
Drop proposalUIDropProposal (.move/.copy)ACTION_DROP + заставице
Међуапликацијско DnDiOS 11+ Split View (iPad)Android 7.0+ Split Screen

Приступачност: корисници са моторним ограничењима можда не ће моћи да изврше гест превлачења. Омогућите алтернативе кроз дугмад „Помери горе/доле” за листе, контекстни мени „Премести у фолдер” за датотеке. 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 користи праг — ако покрет премаши 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. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође