Swipe: ce este, procesarea swipe-urilor în dezvoltarea mobilă

Autor: IT Sectr Publicat: 2026-02-27 Timp de citire: 8 min
Swipe (deplasare) — un gest discret prin care utilizatorul deplasează degetul pe ecran într-o singură direcție — dreapta, stânga, sus sau jos. Spre deosebire de tragere (drag), swipe nu urmărește mișcarea continuă: este recunoscut ca o acțiune finalizată după ce degetul depășește un prag minim și se ridică de pe ecran. Conform studiului UX Nielsen Norman Group (2024), swipe — al doilea cel mai frecvent gest în aplicațiile mobile după tap, utilizat în 23% din interacțiunile utilizatorilor.

Puncte principale

  • Swipe — gest discret: recunoscut ca o singură acțiune finalizată după depășirea pragului și ridicarea degetului.
  • În iOS, procesarea swipe-ului se face prin UISwipeGestureRecognizer cu configurarea direcției (direction) și a numărului de degete.
  • În Android se folosește GestureDetector cu onFling(MotionEvent) sau OnSwipeTouchListener pentru un API simplificat.
  • Pragul swipe-ului — ~20px pe iOS (viewConfiguration) și se configurează prin VelocityTracker în Android.
  • Pentru liste (UITableView/RecyclerView) se folosesc mecanisme integrate — UISwipeActionsConfiguration și ItemTouchHelper — în locul recunoașterii manuale.

Ce este swipe?

Swipe — o mișcare rapidă de alunecare a degetului pe suprafața ecranului, care se termină cu ridicarea. Swipe poate fi scurt (derularea unui element) sau lung (deschiderea unei cortine), dar caracteristica cheie — discretizarea: sistemul îl recunoaște ca un singur eveniment, nu ca o secvență continuă de coordonate.

Sistemele de operare mobile determină swipe-ul după trei parametri: distanța minimă (prag), viteza minimă (velocity) și direcția. Dacă degetul se mișcă lent sau distanța este insuficientă, sistemul interpretează gestul ca panoramare (pan) sau tap. Valorile prag diferă între platforme: iOS folosește constanta UISwipeGestureRecognizer cu un prag fix, Android — ViewConfiguration.getScaledTouchSlop(), care returnează ~8–16 dp în funcție de densitatea ecranului.

Conform Android Developers Documentation, onFling (swipe) în GestureDetector se activează la viteza peste 100 px/s și distanța de la 50px. În IT Sectr folosim swipe pentru navigare (galerii, interfețe card, onboarding) — acest gest este intuitiv pentru utilizatori de toate vârstele.

Swipe vs panoramare: care este diferența?

Swipe și panoramarea (pan/drag) — tipuri diferite de gesturi, deși ambele folosesc mișcarea degetului pe ecran. Swipe este discret și înseamnă „fă o acțiune”, în timp ce panoramarea este continuă și înseamnă „mută obiectul cât timp degetul este pe ecran”.

Parametru Swipe Panoramare (Pan/Drag)
Tip Discret Continuu
Evenimente Unul (recunoscut/nerrecunoscut) Multiple (.began → .changed → .ended)
Viteză Ridicată (mișcare rapidă) Oricare (deplasare lentă)
Exemplu iOS UISwipeGestureRecognizer UIPanGestureRecognizer
Exemplu Android GestureDetector.onFling() GestureDetector.onScroll()
Scenariu Șterge e-mail, întoarce pagina Deplasa harta, trage fișierul
Urmărirea coordonatelor Nu (doar direcție) Da (actualizare continuă a coordonatelor)

Alegerea între swipe și panoramare depinde de sarcină. Pentru acțiuni asupra elementului (ștergere, arhivare, deschidere meniu) folosiți swipe. Pentru manipulare directă (deplasare, scalare) — panoramare. Amestecarea gesturilor pe același element necesită require(toFail:) sau logică personalizată.

Swipe în iOS: UISwipeGestureRecognizer

UISwipeGestureRecognizer — o subclasă a UIGestureRecognizer care recunoaște swipe-ul discret într-una din cele patru direcții. Spre deosebire de UIPanGestureRecognizer, nu generează evenimente intermediare .changed: la recunoaștere, acțiunea este apelată o singură dată.

Proprietatea direction (UISwipeGestureRecognizer.Direction) stabilește direcția urmărită — .left, .right, .up, .down. Se poate combina prin mască: [.left, .right] pentru swipe-uri orizontale. Proprietatea numberOfTouchesRequired determină numărul de degete — implicit 1. UISwipeGestureRecognizer nu are un prag de distanță configurabil — iOS folosește o valoare încorporată de aproximativ 20px, suficientă pentru o recunoaștere fiabilă.

Deoarece UISwipeGestureRecogniser este un recunoscător discret, nu intră în conflict cu UIPanGestureRecognizer: la mișcare lentă se activează pan, la mișcare rapidă — swipe. Totuși, la coexistența cu UITapGestureRecognizer pe aceeași vedere, poate fi necesar require(toFail:) pentru prevenirea recunoașterii false a tap-ului.

Swipe în Android: GestureDetector

În Android, API-ul principal pentru recunoașterea swipe-ului este GestureDetector cu callback-ul OnGestureListener, și anume metoda onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY). GestureDetector analizează poziția inițială și finală a degetului, viteza de mișcare pe axe și distanța, apoi apelează onFling la depășirea pragurilor.

Pragurile minime se configurează prin ViewConfiguration: VelocityTracker.getMinVelocity() (~100 px/s) și ViewConfiguration.getScaledTouchSlop() (~8–16 dp). OnSwipeTouchListener personalizat — un model comun care simplifică API-ul: dezvoltatorul nu trebuie să calculeze manual direcția și viteza. Android Support Library nu conține un „SwipeDetector” încorporat, deci o împachetare personalizată este soluția standard.

Pentru swipe în liste, Google recomandă utilizarea ItemTouchHelper.SimpleCallback din RecyclerView, care abstrage detectarea gestului, animația și callback-urile onSwiped(). În IT Sectr folosim SwipeListener personalizat pentru ViewPager2 și interfețe card — oferind control asupra sensibilității swipe fără a afecta performanța.

Swipe în liste: SwipeActions și ItemTouchHelper

Pentru liste (UITableView, RecyclerView) Apple și Google oferă API-uri specializate care înlocuiesc adăugarea manuală a UISwipeGestureRecognizer. Aceste API-uri suportă butoane de acțiune, animație personalizată și gesturi „deplasează pentru a șterge” — modele standard ale aplicațiilor mobile.

În iOS (11+) se folosește UISwipeActionsConfiguration: metoda tableView(_:leadingSwipeActionsConfigurationForRowAt:) returnează un array de UIContextualAction — butoane cu titlu, stil (destructive, normal) și handler. De exemplu, „Șterge” — .destructive cu fundal roșu, „Arhivă” — .normal cu gri. Sistemul animează singur apariția butoanelor și apelează blocul completion după apăsare.

În Android, ItemTouchHelper.SimpleCallback se atașează la RecyclerView prin ItemTouchHelper.attachToRecyclerView(). Parametri — flag-uri de direcție (start, end, up, down) și callback-ul onSwiped(viewHolder, direction). În interiorul onSwiped se apelează adapter.notifyItemRemoved(position) pentru ștergerea elementului cu animație. ItemTouchHelper gestionează automat gesturile, conflictele cu derularea (scroll) și returnarea elementului dacă swipe-ul nu este finalizat. Conform Google I/O 2024, ItemTouchHelper este utilizat în 70% din aplicațiile Android cu acțiuni de swipe în liste.

Exemple de cod în Swift și Kotlin

Exemplul 1: Swipe la stânga pe iOS (Swift)

Adaugă UISwipeGestureRecognizer pe view pentru revenirea la ecranul anterior. Codul arată configurația minimă a recunoscătorului cu direcția .left.

swift
import UIKit

class CardViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let swipeLeft = UISwipeGestureRecognizer(
            target: self,
            action: #selector(handleSwipeLeft(_:))
        )
        swipeLeft.direction = .left
        swipeLeft.numberOfTouchesRequired = 1
        view.addGestureRecognizer(swipeLeft)
    }

    @objc private func handleSwipeLeft(_: UISwipeGestureRecognizer) {
        guard let nav = navigationController else { return }
        if nav.viewControllers.count > 1 {
            nav.popViewController(animated: true)
        } else {
            nav.dismiss(animated: true)
        }
    }
}

Recunoscătorul se atașează la root-view-ul controller-ului. Verificarea navigationController.viewControllers.count garantează că pop se execută doar când există un ecran anterior în stivă. Pentru controllere modale se folosește dismiss. Codul nu necesită verificarea stării — UISwipeGestureRecognizer este discret și apelează action doar la recunoașterea cu succes.

Exemplul 2: Swipe în Android (Kotlin) cu OnSwipeTouchListener personalizat

Implementează o împachetare simplă a GestureDetector care determină direcția swipe-ului și apelează callback-urile onSwipeLeft/Right.

kotlin
import android.content.Context
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View

open class OnSwipeTouchListener(context: Context) : View.OnTouchListener {

    private val gestureDetector = GestureDetector(context, GestureListener())

    override fun onTouch(v: View, event: MotionEvent): Boolean {
        return gestureDetector.onTouchEvent(event)
    }

    private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {

        companion object {
            private const val SWIPE_THRESHOLD = 100
            private const val SWIPE_VELOCITY_THRESHOLD = 100
        }

        override fun onFling(
            e1: MotionEvent?,
            e2: MotionEvent,
            velocityX: Float,
            velocityY: Float
        ): Boolean {
            val diffX = e2.x - e1!!.x
            val diffY = e2.y - e1.y

            if (Math.abs(diffX) > Math.abs(diffY)) {
                if (Math.abs(diffX) > SWIPE_THRESHOLD
                    && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD
                ) {
                    if (diffX > 0) onSwipeRight()
                    else onSwipeLeft()
                    return true
                }
            } else {
                if (Math.abs(diffY) > SWIPE_THRESHOLD
                    && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD
                ) {
                    if (diffY > 0) onSwipeDown()
                    else onSwipeUp()
                    return true
                }
            }
            return false
        }
    }

    open fun onSwipeLeft() {}
    open fun onSwipeRight() {}
    open fun onSwipeUp() {}
    open fun onSwipeDown() {}
}

OnSwipeTouchListener extinde SimpleOnGestureListener, implementând onFling. diffX/diffY determină direcția, SWIPE_THRESHOLD (100px) și SWIPE_VELOCITY_THRESHOLD (100 px/s) — pragurile. Utilizare: view.setOnTouchListener(OnSwipeTouchListener(context).apply { onSwipeLeft = { dismiss() } }).

Exemplul 3: SwipeActions în iOS (UITableView)

Adaugă un buton de ștergere la swipe-ul spre stânga pe celula tabelului. Folosește API-ul încorporat iOS 11+ fără recunoaștere manuală a gesturilor.

swift
func tableView(
    _ tableView: UITableView,
    trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath
) -> UISwipeActionsConfiguration? {
    let deleteAction = UIContextualAction(
        style: .destructive,
        title: "Șterge"
    ) { _, _, completionHandler in
        items.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .automatic)
        completionHandler(true)
    }
    deleteAction.backgroundColor = .systemRed

    let config = UISwipeActionsConfiguration(actions: [deleteAction])
    config.performsFirstActionWithFullSwipe = true
    return config
}

Metoda returnează UISwipeActionsConfiguration cu un array de UIContextualAction. style: .destructive setează automat fundalul roșu. performsFirstActionWithFullSwipe = true permite executarea acțiunii cu un swipe complet fără apăsare suplimentară. În IT Sectr folosim acest API pentru toate listele cu acțiuni — este standardizat, suportă VoiceOver și nu necesită GestureRecognizer personalizate.

Întrebări frecvente

Cum deosebim swipe-ul de panoramare?

Swipe — gest discret cu mișcare rapidă și ridicare a degetului, panoramarea — tragere continuă cu urmărirea coordonatelor. UISwipeGestureRecognizer se activează o dată, UIPanGestureRecognizer generează .began → .changed → .ended. Alegerea depinde de scenariu: swipe — pentru acțiuni (șterge, întoarce), pan — pentru deplasare (hartă, slider).

Swipe-ul funcționează la fel pe iOS și Android?

Logica gestului este identică, dar API-ul diferă. iOS folosește UISwipeGestureRecognizer cu direction. Android folosește GestureDetector.onFling() cu praguri personalizate. Rezultatul — același UX cu implementări diferite. Framework-urile cross-platform (Flutter, React Native) abstrage diferența printr-un API unitar de swipe.

Cum gestionăm swipe-ul într-o listă?

În iOS (11+) folosiți UISwipeActionsConfiguration în UITableViewDelegate. În Android — ItemTouchHelper.SimpleCallback pentru RecyclerView. Aceste API-uri înlocuiesc GestureRecognizer manuale, suportă butoane de acțiune și animație, gestionează corect conflictul cu derularea și se adaptează la HIG-urile platformei.

Concluzii

  • Swipe — gest discret de alunecare rapidă a degetului, al doilea ca frecvență după tap (23% din interacțiuni).
  • În iOS, UISwipeGestureRecogniser procesează swipe-urile în patru direcții cu un prag fix de ~20px.
  • În Android, GestureDetector.onFling() este utilizat cu praguri personalizate de viteză și distanță.
  • Pentru liste, folosiți UISwipeActionsConfiguration (iOS) și ItemTouchHelper (Android) în locul recunoscătoarelor manuale.
  • Swipe diferă de panoramare prin discretizare și viteză mare — nu confundați aceste gesturi la proiectare.
  • OnSwipeTouchListener personalizat în Android simplifică API-ul GestureDetector, ascunzând calculul direcției.
  • În IT Sectr aplicăm swipe pentru navigare, ștergerea elementelor și onboarding — gestul este intuitiv și nu necesită învățare.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și