Wichtige Punkte
Ein Swipe ist eine schnelle Gleitbewegung eines Fingers über die Bildschirmoberfläche, die mit einem Abheben endet. Ein Swipe kann kurz (Durchblättern eines Elements) oder lang (Öffnen eines Vorhangs) sein, aber das Hauptmerkmal ist die Diskretion: Das System erkennt ihn als einzelnes Ereignis, nicht als kontinuierliche Folge von Koordinaten.
Mobile Betriebssysteme erkennen einen Swipe anhand von drei Parametern: Mindestabstand (Schwellenwert), Mindestgeschwindigkeit (Velocity) und Richtung. Wenn sich der Finger langsam bewegt oder der Abstand nicht ausreicht, interpretiert das System die Geste als Schwenken oder Tippen. Die Schwellenwerte unterscheiden sich zwischen den Plattformen: iOS verwendet eine Konstante in UISwipeGestureRecognizer mit einem festen Schwellenwert, Android verwendet ViewConfiguration.getScaledTouchSlop(), das je nach Bildschirmdichte ~8–16 dp zurückgibt.
Laut Android Developers Documentation wird onFling (Swipe) in GestureDetector bei Geschwindigkeiten über 100 px/s und Entfernungen ab 50px ausgelöst. Bei IT Sectr verwenden wir Swipe für Navigation (Galerien, Kartenoberflächen, Onboarding) — diese Geste ist für Benutzer jeden Alters intuitiv.
Swipe und Schwenken (Pan/Drag) sind verschiedene Gestentypen, obwohl beide das Bewegen eines Fingers über den Bildschirm beinhalten. Swipe ist diskret und bedeutet "eine Aktion ausführen", während Schwenken kontinuierlich ist und bedeutet "ein Objekt bewegen, solange der Finger auf dem Bildschirm ist".
| Parameter | Swipe | Pan/Drag |
|---|---|---|
| Typ | Diskret | Kontinuierlich |
| Ereignisse | Einzelnes (erkannt/nicht erkannt) | Mehrere (.began → .changed → .ended) |
| Geschwindigkeit | Hoch (schnelle Bewegung) | Beliebig (langsame Bewegung) |
| iOS-Beispiel | UISwipeGestureRecognizer | UIPanGestureRecognizer |
| Android-Beispiel | GestureDetector.onFling() | GestureDetector.onScroll() |
| Szenario | E-Mail löschen, Seite umblättern | Karte bewegen, Datei ziehen |
| Koordinatenverfolgung | Nein (nur Richtung) | Ja (ständige Koordinatenaktualisierung) |
Die Wahl zwischen Swipe und Schwenken hängt von der Aufgabe ab. Für Aktionen an einem Element (löschen, archivieren, Menü öffnen) verwenden Sie Swipe. Für direkte Manipulation (bewegen, skalieren) verwenden Sie Schwenken. Das Mischen von Gesten auf demselben Element erfordert require(toFail:) oder benutzerdefinierte Logik.
UISwipeGestureRecognizer ist eine Unterklasse von UIGestureRecognizer, die einen diskreten Swipe in einer von vier Richtungen erkennt. Im Gegensatz zu UIPanGestureRecognizer generiert er keine zwischengeschalteten .changed-Ereignisse: Bei Erkennung wird die Aktion genau einmal aufgerufen.
Die Eigenschaft direction (UISwipeGestureRecognizer.Direction) legt die verfolgte Richtung fest — .left, .right, .up, .down. Richtungen können über eine Maske kombiniert werden: [.left, .right] für horizontale Swipes. Die Eigenschaft numberOfTouchesRequired bestimmt die Anzahl der Finger — standardmäßig 1. UISwipeGestureRecognizer hat keinen konfigurierbaren Abstandsschwellenwert — iOS verwendet einen integrierten Wert von etwa 20px, der für eine zuverlässige Erkennung ausreicht.
Da UISwipeGestureRecognizer ein diskreter Erkerner ist, konfligiert er nicht mit UIPanGestureRecognizer: Langsame Bewegung löst pan aus, schnelle Bewegung löst swipe aus. Bei Koexistenz mit UITapGestureRecognizer auf derselben View kann jedoch require(toFail:) erforderlich sein, um eine falsche Tipp-Erkennung zu verhindern.
In Android ist die primäre API für die Swipe-Erkennung GestureDetector mit dem OnGestureListener-Callback, insbesondere die Methode onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY). GestureDetector analysiert die Anfangs- und Endposition des Fingers, die Bewegungsgeschwindigkeit entlang der Achsen und die Entfernung und ruft dann onFling auf, wenn Schwellenwerte überschritten werden.
Mindestschwellenwerte werden über ViewConfiguration konfiguriert: VelocityTracker.getMinVelocity() (~100 px/s) und ViewConfiguration.getScaledTouchSlop() (~8–16 dp). Ein benutzerdefinierter OnSwipeTouchListener ist ein gängiges Muster, das die API vereinfacht: Der Entwickler muss Richtung und Geschwindigkeit nicht manuell berechnen. Die Android Support Library enthält keinen integrierten "SwipeDetector", daher ist ein benutzerdefinierter Wrapper die Standardlösung.
Für Swipe in Listen empfiehlt Google die Verwendung von ItemTouchHelper.SimpleCallback aus RecyclerView, das die Gestenerkennung, Animation und onSwiped()-Callbacks abstrahiert. Bei IT Sectr verwenden wir einen benutzerdefinierten SwipeListener für ViewPager2 und Kartenoberflächen — dies gibt Kontrolle über die Swipe-Empfindlichkeit ohne Leistungseinbußen.
Für Listen (UITableView, RecyclerView) bieten Apple und Google spezialisierte APIs, die das manuelle Hinzufügen von UISwipeGestureRecognizer ersetzen. Diese APIs unterstützen Aktionsschaltflächen, benutzerdefinierte Animationen und "Zum Löschen wischen"-Gesten — Standardmuster in mobilen Anwendungen.
In iOS (11+) wird UISwipeActionsConfiguration verwendet: Die Methode tableView(_:leadingSwipeActionsConfigurationForRowAt:) gibt ein Array von UIContextualAction zurück — Schaltflächen mit Titel, Stil (destructive, normal) und Handler. Zum Beispiel "Löschen" — .destructive mit rotem Hintergrund, "Archivieren" — .normal mit grauem Hintergrund. Das System animiert das Erscheinen der Schaltflächen und ruft nach einem Tippen den completion-Block auf.
In Android wird ItemTouchHelper.SimpleCallback über ItemTouchHelper.attachToRecyclerView() an RecyclerView angehängt. Zu den Parametern gehören Richtungsflags (start, end, up, down) und der Callback onSwiped(viewHolder, direction). Innerhalb von onSwiped wird adapter.notifyItemRemoved(position) aufgerufen, um das Element mit Animation zu entfernen. ItemTouchHelper verarbeitet automatisch Gesten, Scrollkonflikte und die Rückführung des Elements, wenn der Swipe nicht abgeschlossen wird. Laut Google I/O 2024 wird ItemTouchHelper in 70% der Android-Apps mit Swipe-Aktionen in Listen verwendet.
Fügt einer View einen UISwipeGestureRecognizer hinzu, um zum vorherigen Bildschirm zurückzukehren. Der Code zeigt die minimale Erkerner-Konfiguration mit der Richtung .left.
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)
}
}
}
Der Erkerner wird an die Root-View des Controllers angehängt. Die Prüfung navigationController.viewControllers.count stellt sicher, dass pop nur ausgeführt wird, wenn ein vorheriger Bildschirm im Stapel vorhanden ist. Für modale Controller wird dismiss verwendet. Der Code erfordert keine Zustandsprüfung — UISwipeGestureRecognizer ist diskret und ruft die Aktion nur bei erfolgreicher Erkennung auf.
Implementiert einen einfachen GestureDetector-Wrapper, der die Swipe-Richtung bestimmt und onSwipeLeft/Right-Callbacks aufruft.
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 erweitert SimpleOnGestureListener und implementiert onFling. diffX/diffY bestimmen die Richtung, SWIPE_THRESHOLD (100px) und SWIPE_VELOCITY_THRESHOLD (100 px/s) sind die Schwellenwerte. Verwendung: view.setOnTouchListener(OnSwipeTouchListener(context).apply { onSwipeLeft = { dismiss() } }).
Fügt beim Wischen nach links über eine Tabellenzelle eine Löschschaltfläche hinzu. Verwendet die integrierte iOS 11+ API ohne manuelle Gestenerkennung.
func tableView(
_ tableView: UITableView,
trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath
) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(
style: .destructive,
title: "Löschen"
) { _, _, 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
}
Die Methode gibt UISwipeActionsConfiguration mit einem Array von UIContextualAction zurück. style: .destructive setzt automatisch den roten Hintergrund. performsFirstActionWithFullSwipe = true ermöglicht die Ausführung der Aktion mit einem vollständigen Wisch ohne zusätzliches Tippen. Bei IT Sectr verwenden wir diese API für alle Listen mit Aktionen — sie ist standardisiert, unterstützt VoiceOver und benötigt keine benutzerdefinierten GestureRecognizer.
Häufig gestellte Fragen
Swipe ist eine diskrete Geste mit schneller Bewegung und Fingerabheben, Schwenken ist kontinuierliches Ziehen mit Koordinatenverfolgung. UISwipeGestureRecognizer wird einmal ausgelöst, UIPanGestureRecognizer erzeugt .began → .changed → .ended. Die Wahl hängt vom Szenario ab: Swipe für Aktionen (löschen, umblättern), Pan für Bewegung (Karte, Schieberegler).
Die Gestenlogik ist identisch, aber die API unterscheidet sich. iOS verwendet UISwipeGestureRecognizer mit direction. Android verwendet GestureDetector.onFling() mit benutzerdefinierten Schwellenwerten. Das Ergebnis ist dieselbe UX bei unterschiedlicher Implementierung. Plattformübergreifende Frameworks (Flutter, React Native) abstrahieren den Unterschied durch eine einheitliche Swipe-API.
Verwenden Sie in iOS (11+) UISwipeActionsConfiguration im UITableViewDelegate. Verwenden Sie in Android ItemTouchHelper.SimpleCallback für RecyclerView. Diese APIs ersetzen manuelle GestureRecognizer, unterstützen Aktionsschaltflächen und Animationen, behandeln Scrollkonflikte korrekt und passen sich den plattformspezifischen HIGs an.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch