Drag-and-Drop — istota, Drag and Drop w aplikacjach mobilnych

Autor: IT Sectr Opublikowano: 2026-02-27 Czas czytania: 9 min

Drag-and-Drop — interaktywny gest przeciągania wizualnego obiektu po ekranie za pomocą palca. Gest składa się z trzech faz: chwyt (long press lub dotknięcie), przesuwanie (ruch palca z obiektem) i puszczenie (zrzucenie w docelowej strefie). Służy do zmiany kolejności elementów, przenoszenia plików między folderami, organizacji interfejsu (drag to reorder, drag to resize). W iOS realizowany poprzez UIDragInteraction, w Androidzie — poprzez DragEvent i startDragAndDrop.

Najważniejsze

  • Trzy fazy — Drag-and-Drop składa się z chwytu, przesuwania i puszczenia obiektu
  • UIDragInteraction — główna klasa iOS do inicjowania i obsługi przeciągania
  • startDragAndDrop — metoda Android View do rozpoczęcia przeciągania po chwycie
  • Drag shadow — wizualny cień przeciąganego obiektu, podążający za palcem
  • Drop target — strefa zrzutu, która podświetla się po najechaniu przeciąganym obiektem

Czym jest Drag-and-Drop?

Drag-and-Drop (DnD, przeciąganie) — metoda manipulacji graficznymi elementami interfejsu, w której użytkownik chwyta obiekt palcem lub myszą, przenosi go w inne miejsce i puszcza. W interfejsach mobilnych Drag-and-Drop jest zwykle inicjowany długim przytrzymaniem (Long Press) — użytkownik przytrzymuje element przez 300–500 ms, po czym system przełącza interfejs w tryb przeciągania, a ruch palca przesuwa obiekt za sobą.

Historycznie Drag-and-Drop pojawił się w interfejsach desktopowych (Xerox Star, 1981; Macintosh, 1984) jako alternatywa dla poleceń kopiuj/wklej. Na platformach mobilnych pełne wsparcie pojawiło się w iOS 11 (2017) z UIDragInteraction i w Android 7.0 (2016) z Multi-Window Drag-and-Drop. Wcześniej przeciąganie w aplikacjach mobilnych było realizowane przez niestandardowe rozwiązania z użyciem gesture recognizers.

Kluczowe koncepcje: drag session (sesja przeciągania), drag items (przeciągane obiekty), drag preview (wizualny obraz obiektu), drop target (strefa zrzutu), drop proposal (akcja przy zrzucie: przenieś, kopiuj, połącz). System zarządza sesją na poziomie systemu operacyjnego, co umożliwia przeciąganie obiektów między różnymi aplikacjami (np. zdjęcie z Galerii do Notatek).

Fazy Drag-and-Drop

Drag-and-Drop dzieli się na trzy następujące po sobie fazy. Faza 1 — chwyt (Drag Start): użytkownik inicjuje gest (zwykle Long Press), system tworzy sesję przeciągania, przechwytuje dane obiektu i wyświetla drag preview — półprzezroczystą kopię elementu podążającą za palcem. W tej fazie system odrzuca inne gesty (przewijanie, zaznaczanie tekstu) do zakończenia DnD.

Faza 2 — przesuwanie (Drag Move): palec porusza się po ekranie, drag preview podąża za punktem dotyku. System nieprzerwanie określa drop target pod palcem i wysyła zdarzenia drag enter, drag move i drag exit. Drop target może reagować wizualnie: podświetlać się, rozszerzać lub pokazywać linię-wstawkę. Ta faza trwa od 0.5 do 10+ sekund w zależności od złożoności zadania.

Faza 3 — puszczenie (Drop): palec odrywa się od ekranu. System kończy sesję przeciągania i wywołuje drop callback u docelowego elementu. Jeśli drop target odrzuca zrzut (np. przeciąganie pliku do folderu bez uprawnień zapisu), drag preview animacyjnie wraca do pierwotnej pozycji (cancel animation). Jeśli zrzut jest zaakceptowany, element znika z pierwotnej pozycji i pojawia się w docelowej.

FazaZdarzenie iOSZdarzenie AndroidStan wizualny
ChwytUIDragInteractionDelegate.dragSessionWillBeginView.OnLongClickListener → startDragAndDropDrag preview pojawia się pod palcem
PrzesuwanieUIDropInteractionDelegate.dragSessionDidUpdateView.OnDragListener.onDrag (ACTION_DRAG_MOVED)Preview się porusza, target podświetlony
PuszczenieUIDropInteractionDelegate.performDropView.OnDragListener.onDrag (ACTION_DROP)Animacja zrzutu lub powrotu

Przeciąganie między aplikacjami — funkcja dostępna na obu platformach. iOS obsługuje Drag-and-Drop między aplikacjami w trybie Split View i Slide Over (iPad). Android obsługuje przeciąganie między aplikacjami w trybie Split Screen. Dane są przesyłane przez UIPasteConfiguration (iOS) lub ClipData (Android). Deweloper określa obsługiwane typy danych (UTI dla iOS, MIME dla Androida).

Drag-and-Drop w iOS: UIDragInteraction

UIDragInteraction — główne API iOS do przeciągania, dodane w iOS 11. Aby włączyć przeciąganie z View, dodaj UIDragInteraction z UIDragInteractionDelegate. Delegat określa, które elementy są przeciągane, ich wygląd i zachowanie. Do przyjmowania elementów używa się UIDropInteraction z UIDropInteractionDelegate, który określa, czy View może przyjąć zrzut i jak przetworzyć dane.

swift
// UIDragInteraction — przeciąganie elementu z kolekcji
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 — zmniejszona kopia elementu
        dragItem.previewProvider = {
            let previewView = UIImageView(image: thumbnailImage)
            previewView.alpha = 0.8
            return UIDragPreview(view: previewView)
        }
        return [dragItem]
    }
}

UIDropInteractionDelegate — lustrzany interfejs do przyjmowania zrzutu. Metoda canHandle(_:) sprawdza, czy typ danych jest obsługiwany. sessionDidUpdate(_:) wizualnie aktualizuje stan (podświetlenie, linia-wstawka). performDrop(_:) wykonuje końcowe przetwarzanie danych. iOS automatycznie wywołuje UIDropProposal z typem operacji: .move (przenieś), .copy (kopiuj), .forbidden (zabronione). Typ operacji wpływa na wyświetlanie wizualne (ikona + w rogu preview dla kopiowania, znak zakazu dla forbidden).

Drag-and-Drop w Androidzie: startDragAndDrop

View.startDragAndDrop() — metoda Android SDK do rozpoczęcia przeciągania, dostępna od API 24 (Android 7.0). Wywoływana po chwycie elementu (zwykle w onLongClick). Parametry: ClipData (dane), DragShadowBuilder (wizualny cień), Object myLocalState (stan lokalny), flags. DragShadowBuilder tworzy Bitmap, który podąża za palcem. System automatycznie zarządza animacją i zdarzeniami dotykowymi podczas przeciągania.

kotlin
// Drag-and-Drop elementu RecyclerView z zmianą kolejności
class ReorderAdapter(private val items: MutableList<String>) :
    RecyclerView.Adapter<ReorderAdapter.ViewHolder>() {

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.itemView.setOnLongClickListener {
            // Tworzymy ClipData do przesyłania danych
            val clipData = ClipData.newPlainText("item", items[position])

            // Niestandardowy DragShadowBuilder z zmniejszonym 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
        }
    }
}

Przyjmowanie zrzutu w Androidzie realizowane jest przez View.setOnDragListener(). Słuchacz otrzymuje zdarzenia ACTION_DRAG_STARTED, ACTION_DRAG_ENTERED, ACTION_DRAG_LOCATION, ACTION_DRAG_EXITED, ACTION_DROP, ACTION_DRAG_ENDED. W zdarzeniu ACTION_DROP dane są wyodrębniane z ClipData i wykonywana jest docelowa akcja. Dla RecyclerView z zmienianiem kolejności zalecany jest ItemTouchHelper.SimpleCallback — wbudowany mechanizm, który automatycznie obsługuje Long Press do chwytu, animację przesuwania elementów oraz metody pomocnicze onMove/onSwiped.

Scenariusze zastosowania Drag-and-Drop

Zmienianie kolejności list (drag to reorder) — najczęstszy scenariusz DnD: użytkownik przeciąga elementy listy, aby zmienić ich kolejność. Przykłady: przestawianie kontaktów w ulubionych, sortowanie zadań w trackerach (Trello, Todoist), zmiana kolejności utworów w playliście (Spotify, Apple Music). Realizowane przez ItemTouchHelper w Androidzie lub UILongPressGestureRecognizer + przestawianie komórek w iOS.

Menedżery plików — Drag-and-Drop do kopiowania i przenoszenia plików między folderami. iOS Files App, Android Files by Google, Dropbox — wszystkie obsługują DnD. Przeciągnięcie pliku na folder przenosi go do środka (move), przeciągnięcie z przytrzymanym klawiszem Option/Ctrl — kopiuje (copy). Drop target wizualnie podświetla się po najechaniu, pokazując granice folderu.

Tablice Kanban — Trello, Jira, Notion używają Drag-and-Drop do przenoszenia kart między kolumnami (To Do → In Progress → Done). Podczas przeciągania karta odczepia się od źródłowej kolumny, podąża za palcem, a po przekroczeniu granicy innej kolumny wstawiana jest z animacją. iOS 11+ obsługuje UIDragPreview z efektem paralaksy, gdzie preview lekko odchyla się od punktu dotyku, tworząc głębię.

Sekcje Springboard (iOS) — przeciąganie ikon aplikacji na ekranie głównym iOS. Długie przytrzymanie ikony aktywuje tryb „jiggling” (ikony się trzęsą), po czym użytkownik może przenosić ikony między stronami i tworzyć foldery. To jeden z najtrudniejszych wzorców UX DnD, ponieważ wymaga jednoczesnej obsługi przeciągania, animacji trzęsienia i grupowania w foldery.

Zalecenia UX dla Drag-and-Drop

Informacja zwrotna wizualna — krytycznie ważna dla Drag-and-Drop. Przeciągany obiekt powinien się zmienić: zmniejszyć (iOS: scale 0.8–0.9), stać się półprzezroczystym (alpha 0.7–0.8) i unieść się nad interfejsem z cieniem (shadow offset). Drop target powinien reagować wizualnie na najechanie: podświetlać się (highlight), rozszerzać (expand) lub pokazywać granice (border). Bez tych sygnałów użytkownik nie rozumie, gdzie można upuścić obiekt.

Animacja powrotu (drag cancel) — jeśli użytkownik puści element poza strefą zrzutu lub nad nieprawidłową strefą, obiekt powinien animacyjnie wrócić do pierwotnej pozycji. iOS UIDragInteractionDelegate udostępnia dragInteraction(_:sessionDidMove:) do śledzenia oraz dragInteraction(_:session:willEndWith:) do animacji powrotu. Android View.setOnDragListener otrzymuje ACTION_DRAG_ENDED, gdzie można uruchomić animację powrotu przez ValueAnimator lub ObjectAnimator.

ZalecenieiOSAndroid
Chwyt gestemLong Press (domyślnie)OnLongClickListener
Drag previewUIDragItem.previewProviderDragShadowBuilder
Informacja dotykowaUIImpactFeedbackGeneratorHapticFeedbackConstants.LONG_PRESS
Animacja powrotuUIDragPreviewTargetViewPropertyAnimator
Drop proposalUIDropProposal (.move/.copy)ACTION_DROP + flagi
Międzyaplikacyjne DnDiOS 11+ Split View (iPad)Android 7.0+ Split Screen

Dostępność: użytkownicy z ograniczeniami motorycznymi mogą nie być w stanie wykonać gestu przeciągania. Zapewnij alternatywy poprzez przyciski „Przenieś w górę/dół” dla list, menu kontekstowe „Przenieś do folderu” dla plików. iOS VoiceOver obsługuje działanie rotora „Drag” do przenoszenia elementów. Android TalkBack zapewnia niestandardowe działania przez AccessibilityNodeInfo.addAction(). Nike Run Club i Apple Health używają DnD do zmiany kolejności metryk na pulpicie — z dostępem przez standardowe przyciski.

Często zadawane pytania

Jaki gest jest używany do inicjowania Drag-and-Drop?

Standardowym gestem do rozpoczęcia Drag-and-Drop jest Long Press (długie przytrzymanie) trwające 300–500 ms. iOS używa wbudowanego mechanizmu UIDragInteraction, który automatycznie konwertuje długi dotyk na chwyt. Android wymaga jawnego wywołania startDragAndDrop() w callbacku OnLongClickListener. W niektórych przypadkach (np. w grach) DnD może zaczynać się od zwykłego dotknięcia bez opóźnienia.

Czy można przeciągać obiekty między różnymi aplikacjami?

Tak, międzyaplikacyjny Drag-and-Drop jest obsługiwany w iOS 11+ (iPad) i Android 7.0+. Na iPadzie przeciąganie działa w trybie Split View i Slide Over — użytkownik może wziąć tekst z Safari i przenieść go do Notatek. W Androidzie DnD między aplikacjami działa w Split Screen. Dane są przesyłane przez UIPasteConfiguration (iOS) lub ClipData (Android) z określeniem obsługiwanych typów (UTI, MIME).

Jak zapobiec konfliktowi Drag-and-Drop z przewijaniem?

Konflikt DnD i Scroll rozwiązuje się poprzez opóźnienie chwytu. Jeśli użytkownik zacznie ruch palca przed upływem limitu czasu Long Press (500 ms), gest jest interpretowany jako przewijanie, a nie Drag-and-Drop. W iOS UIDragInteraction automatycznie zarządza tym konfliktem przez cancelsTouchesInView. W Androidzie ItemTouchHelper używa progu — jeśli ruch przekroczy próg TouchSlop, Long Press jest anulowany na rzecz przewijania.

Jakie dane można przesyłać podczas przeciągania?

Drag-and-Drop obsługuje dowolne typy danych: tekst, obrazy, pliki, URL, niestandardowe obiekty. iOS używa NSItemProvider z typami UTI (public.text, public.image, public.file-url). Android — ClipData z typami MIME (text/plain, image/png, application/octet-stream). Dla niestandardowych danych tworzy się ClipData.Item z Intent. Przy międzyaplikacyjnym DnD dane są pakowane w uniwersalne formaty: plain text, HTML, RTF, UIImage/PNG.

Jak animować powrót elementu przy anulowaniu Drag-and-Drop?

W iOS animacja powrotu jest obsługiwana przez UIDragPreviewTarget — końcową pozycję, do której animacyjnie wraca preview. W Androidzie użyj ViewPropertyAnimator z translateX/translateY do powrotu elementu do pierwotnej pozycji. Czas animacji — 200–300 ms z krzywą easing (EaseOut). UIKit automatycznie dodaje UIDragPreview z efektem paralaksy, który płynnie wraca przy anulowaniu gestu.

Podsumowanie

  • Drag-and-Drop — metoda przeciągania obiektów z trzema fazami: chwyt, przesuwanie, puszczenie
  • Inicjalizacja — zwykle przez Long Press (300–500 ms) dla odróżnienia od przewijania
  • iOS API — UIDragInteraction (źródło) + UIDropInteraction (odbiornik)
  • Android API — View.startDragAndDrop() (źródło) + View.setOnDragListener (odbiornik)
  • ItemTouchHelper — gotowe rozwiązanie Android do zmiany kolejności w RecyclerView
  • Drag preview — wizualny cień obiektu, podążający za palcem z półprzezroczystością
  • Animacja powrotu — obowiązkowa przy zrzucie poza prawidłową strefą dla czytelnego UX

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również