Swipe: o que é, manipulação de deslizes no desenvolvimento móvel

Autor: IT Sectr Publicado: 2026-02-27 Tempo de leitura: 8 min
Swipe (deslize) é um gesto discreto no qual o usuário desliza um dedo pela tela em uma direção — direita, esquerda, cima ou baixo. Ao contrário do arrastar (drag), o deslize não rastreia o movimento contínuo: ele é reconhecido como uma ação concluída após o dedo ultrapassar um limite mínimo e se levantar da tela. De acordo com um estudo de UX da Nielsen Norman Group (2024), swipe é o segundo gesto mais frequente em aplicativos móveis depois do toque, utilizado em 23% das interações do usuário.

Principais pontos

  • Swipe é um gesto discreto: reconhecido como uma ação concluída após ultrapassar o limite e levantar o dedo.
  • No iOS, o deslize é feito via UISwipeGestureRecognizer com configuração de direção e número de dedos.
  • No Android, usa-se GestureDetector com onFling(MotionEvent) ou OnSwipeTouchListener para uma API simplificada.
  • O limite de deslize é de ~20px no iOS (viewConfiguration) e configurável via VelocityTracker no Android.
  • Para listas (UITableView/RecyclerView), usam-se mecanismos integrados — UISwipeActionsConfiguration e ItemTouchHelper — em vez do reconhecimento manual.

O que é um deslize?

Deslize é um movimento rápido e deslizante do dedo sobre a superfície da tela, terminando com a remoção do dedo. Um deslize pode ser curto (passar um elemento) ou longo (abrir uma cortina), mas a principal característica é a discrição: o sistema o reconhece como um único evento, não como uma sequência contínua de coordenadas.

Os sistemas operacionais móveis detectam um deslize com base em três parâmetros: distância mínima (limiar), velocidade mínima (velocity) e direção. Se o dedo se move lentamente ou a distância é insuficiente, o sistema interpreta o gesto como panorâmica ou toque. Os valores de limiar diferem entre plataformas: o iOS usa uma constante no UISwipeGestureRecognizer com um limiar fixo, o Android usa ViewConfiguration.getScaledTouchSlop(), que retorna ~8–16 dp dependendo da densidade da tela.

De acordo com a Documentação para desenvolvedores Android, onFling (swipe) no GestureDetector é acionado em velocidades acima de 100 px/s e distâncias a partir de 50px. Na IT Sectr, usamos deslize para navegação (galerias, interfaces de cartão, integração) — este gesto é intuitivo para usuários de todas as idades.

Swipe vs panorâmica: qual a diferença?

Deslize e panorâmica (pan/drag) são tipos diferentes de gestos, embora ambos envolvam mover o dedo pela tela. O deslize é discreto e significa "realizar uma ação", enquanto a panorâmica é contínua e significa "mover um objeto enquanto o dedo estiver na tela".

Parâmetro Swipe Pan/Drag
Tipo Discreto Contínuo
Eventos Único (reconhecido/não reconhecido) Múltiplos (.began → .changed → .ended)
Velocidade Alta (movimento rápido) Qualquer (movimento lento)
Exemplo iOS UISwipeGestureRecognizer UIPanGestureRecognizer
Exemplo Android GestureDetector.onFling() GestureDetector.onScroll()
Cenário Excluir e-mail, virar página Mover mapa, arrastar arquivo
Rastreamento de coordenadas Não (apenas direção) Sim (atualização constante de coordenadas)

A escolha entre deslize e panorâmica depende da tarefa. Para ações em um elemento (excluir, arquivar, abrir menu) use deslize. Para manipulação direta (mover, dimensionar) use panorâmica. Misturar gestos no mesmo elemento requer require(toFail:) ou lógica personalizada.

Swipe no iOS: UISwipeGestureRecognizer

UISwipeGestureRecognizer é uma subclasse de UIGestureRecognizer que reconhece um deslize discreto em uma das quatro direções. Ao contrário do UIPanGestureRecognizer, ele não gera eventos .changed intermediários: quando reconhecido, a ação é chamada exatamente uma vez.

A propriedade direction (UISwipeGestureRecognizer.Direction) define a direção rastreada — .left, .right, .up, .down. As direções podem ser combinadas usando uma máscara: [.left, .right] para deslizes horizontais. A propriedade numberOfTouchesRequired determina o número de dedos — 1 por padrão. O UISwipeGestureRecognizer não tem um limite de distância configurável — o iOS usa um valor interno de cerca de 20px, suficiente para reconhecimento confiável.

Como o UISwipeGestureRecognizer é um reconhecedor discreto, ele não entra em conflito com o UIPanGestureRecognizer: movimento lento aciona pan, movimento rápido aciona swipe. No entanto, ao coexistir com UITapGestureRecognizer na mesma view, pode ser necessário require(toFail:) para evitar reconhecimento falso de toque.

Swipe no Android: GestureDetector

No Android, a principal API para reconhecimento de deslize é GestureDetector com o callback OnGestureListener, especificamente o método onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY). O GestureDetector analisa a posição inicial e final do dedo, a velocidade do movimento nos eixos e a distância, e então chama onFling quando os limiares são excedidos.

Os limiares mínimos são configuráveis via ViewConfiguration: VelocityTracker.getMinVelocity() (~100 px/s) e ViewConfiguration.getScaledTouchSlop() (~8–16 dp). Um OnSwipeTouchListener personalizado é um padrão comum que simplifica a API: o desenvolvedor não precisa calcular manualmente a direção e a velocidade. A Android Support Library não inclui um "SwipeDetector" interno, portanto um wrapper personalizado é a solução padrão.

Para deslizar em listas, o Google recomenda usar ItemTouchHelper.SimpleCallback do RecyclerView, que abstrai a detecção de gestos, animação e callbacks onSwiped(). Na IT Sectr, usamos um SwipeListener personalizado para ViewPager2 e interfaces de cartão — isso dá controle sobre a sensibilidade do deslize sem sacrificar o desempenho.

Swipe em listas: SwipeActions e ItemTouchHelper

Para listas (UITableView, RecyclerView), Apple e Google fornecem APIs especializadas que substituem a adição manual de UISwipeGestureRecognizer. Essas APIs suportam botões de ação, animação personalizada e gestos "deslizar para excluir" — padrões comuns em aplicativos móveis.

No iOS (11+), usa-se UISwipeActionsConfiguration: o método tableView(_:leadingSwipeActionsConfigurationForRowAt:) retorna um array de UIContextualAction — botões com título, estilo (destructive, normal) e manipulador. Por exemplo, "Excluir" — .destructive com fundo vermelho, "Arquivar" — .normal com fundo cinza. O sistema anima o aparecimento dos botões e chama o bloco completion após um toque.

No Android, ItemTouchHelper.SimpleCallback é anexado ao RecyclerView via ItemTouchHelper.attachToRecyclerView(). Os parâmetros incluem flags de direção (start, end, up, down) e o callback onSwiped(viewHolder, direction). Dentro de onSwiped, adapter.notifyItemRemoved(position) é chamado para remover o item com animação. O ItemTouchHelper gerencia automaticamente gestos, conflitos de rolagem e retorno do item se o deslize não for concluído. De acordo com o Google I/O 2024, o ItemTouchHelper é usado em 70% dos aplicativos Android com ações de deslize em listas.

Exemplos de código em Swift e Kotlin

Exemplo 1: Deslizar para a esquerda no iOS (Swift)

Adiciona UISwipeGestureRecognizer a uma view para retornar à tela anterior. O código mostra a configuração mínima do reconhecedor com a direção .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)
        }
    }
}

O reconhecedor é anexado à view raiz do controlador. A verificação navigationController.viewControllers.count garante que pop só seja executado quando houver uma tela anterior na pilha. Para controladores modais, usa-se dismiss. O código não requer verificação de estado — UISwipeGestureRecognizer é discreto e chama a ação apenas após reconhecimento bem-sucedido.

Exemplo 2: Swipe no Android (Kotlin) com OnSwipeTouchListener personalizado

Implementa um wrapper simples do GestureDetector que determina a direção do deslize e chama os callbacks 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 estende SimpleOnGestureListener, implementando onFling. diffX/diffY determinam a direção, SWIPE_THRESHOLD (100px) e SWIPE_VELOCITY_THRESHOLD (100 px/s) são os limiares. Uso: view.setOnTouchListener(OnSwipeTouchListener(context).apply { onSwipeLeft = { dismiss() } }).

Exemplo 3: SwipeActions no iOS (UITableView)

Adiciona um botão de excluir ao deslizar para a esquerda em uma célula de tabela. Usa a API integrada do iOS 11+ sem reconhecimento manual de gestos.

swift
func tableView(
    _ tableView: UITableView,
    trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath
) -> UISwipeActionsConfiguration? {
    let deleteAction = UIContextualAction(
        style: .destructive,
        title: "Excluir"
    ) { _, _, 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
}

O método retorna UISwipeActionsConfiguration com um array de UIContextualAction. style: .destructive define automaticamente o fundo vermelho. performsFirstActionWithFullSwipe = true permite executar a ação com um deslize completo sem toque adicional. Na IT Sectr, usamos esta API para todas as listas com ações — é padronizada, suporta VoiceOver e não requer GestureRecognizers personalizados.

Perguntas frequentes

Como distinguir um deslize de uma panorâmica?

O deslize é um gesto discreto com movimento rápido e remoção do dedo, a panorâmica é um arrasto contínuo com rastreamento de coordenadas. UISwipeGestureRecognizer é acionado uma vez, UIPanGestureRecognizer gera .began → .changed → .ended. A escolha depende do cenário: deslize para ações (excluir, virar), pan para movimento (mapa, controle deslizante).

O deslize funciona igual no iOS e Android?

A lógica do gesto é idêntica, mas a API difere. O iOS usa UISwipeGestureRecognizer com direction. O Android usa GestureDetector.onFling() com limiares personalizados. O resultado é o mesmo UX com implementações diferentes. Frameworks multiplataforma (Flutter, React Native) abstraem a diferença através de uma API de deslize unificada.

Como lidar com um deslize em uma lista?

No iOS (11+), use UISwipeActionsConfiguration no UITableViewDelegate. No Android, use ItemTouchHelper.SimpleCallback para RecyclerView. Essas APIs substituem GestureRecognizers manuais, suportam botões de ação e animação, lidam corretamente com conflitos de rolagem e se adaptam às HIGs da plataforma.

Resumo

  • O deslize é um gesto discreto de deslizamento rápido do dedo, o segundo mais frequente após o toque (23% das interações).
  • No iOS, o UISwipeGestureRecognizer gerencia deslizes em quatro direções com um limiar fixo de ~20px.
  • No Android, GestureDetector.onFling() é usado com limiares personalizados de velocidade e distância.
  • Para listas, use UISwipeActionsConfiguration (iOS) e ItemTouchHelper (Android) em vez de reconhecedores manuais.
  • O deslize difere da panorâmica em discrição e alta velocidade — não confunda esses gestos ao projetar.
  • Um OnSwipeTouchListener personalizado no Android simplifica a API do GestureDetector ocultando o cálculo de direção.
  • Na IT Sectr, usamos deslize para navegação, exclusão de itens e integração — o gesto é intuitivo e não requer aprendizado.

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também