Főbb pontok
Swipe — az ujj gyors csúsztató mozgása a képernyő felületén, amely felemelkedéssel végződik. A swipe lehet rövid (elem görgetése) vagy hosszú (függöny kinyitása), de a legfontosabb jellemző a diszkrétség: a rendszer egyetlen eseményként ismeri fel, nem pedig a koordináták folyamatos sorozataként.
A mobil operációs rendszerek három paraméter alapján határozzák meg a swipe-ot: minimális távolság (küszöb), minimális sebesség (velocity) és irány. Ha az ujj lassan mozog vagy a távolság nem elegendő, a rendszer a gesztust panorámázásként (pan) vagy tapként értelmezi. A küszöbértékek platformonként eltérőek: iOS a UISwipeGestureRecognizer konstansát használja rögzített küszöbbel, Android — ViewConfiguration.getScaledTouchSlop(), amely ~8–16 dp-t ad vissza a képernyő sűrűségétől függően.
A Android Developers Documentation szerint az onFling (swipe) a GestureDetector-ben 100 px/s feletti sebességnél és 50px távolságtól aktiválódik. Az IT Sectr-ben a swipe-ot navigációra használjuk (galériák, kártya interfészek, onboarding) — ez a gesztus intuitív minden korosztály számára.
Swipe és panorámázás (pan/drag) különböző gesztustípusok, bár mindkettő az ujj mozgását használja a képernyőn. A swipe diszkrét és azt jelenti: „végy egy műveletet”, míg a panorámázás folyamatos és azt jelenti: „mozgasd az objektumot, amíg az ujj a képernyőn van”.
| Paraméter | Swipe | Panorámázás (Pan/Drag) |
|---|---|---|
| Típus | Diszkrét | Folyamatos |
| Események | Egy (felismerve/nem felismerve) | Több (.began → .changed → .ended) |
| Sebesség | Magas (gyors mozgás) | Bármilyen (lassú mozgás) |
| Példa iOS | UISwipeGestureRecognizer | UIPanGestureRecognizer |
| Példa Android | GestureDetector.onFling() | GestureDetector.onScroll() |
| Forgatókönyv | Email törlése, oldal lapozása | Térkép mozgatása, fájl húzása |
| Koordináta követés | Nem (csak irány) | Igen (folyamatos koordináta frissítés) |
A swipe és panorámázás közötti választás a feladattól függ. Az elemen végzett műveletekhez (törlés, archiválás, menü megnyitása) használjon swipe-ot. Közvetlen manipulációhoz (mozgatás, méretezés) — panorámázást. Gesztusok keverése egy elemen require(toFail:) vagy egyedi logikát igényel.
UISwipeGestureRecognizer — a UIGestureRecognizer alosztálya, amely diszkrét swipe-ot ismer fel négy irány egyikében. A UIPanGestureRecognizer-től eltérően nem generál köztes .changed eseményeket: felismeréskor az action pontosan egyszer kerül meghívásra.
A direction tulajdonság (UISwipeGestureRecognizer.Direction) beállítja a követett irányt — .left, .right, .up, .down. Maszkon keresztül kombinálható: [.left, .right] vízszintes csúsztatásokhoz. A numberOfTouchesRequired tulajdonság határozza meg az ujjak számát — alapértelmezés szerint 1. A UISwipeGestureRecognizer-nek nincs beállítható távolság küszöbe — az iOS beépített értéket használ, körülbelül 20px-t, ami elegendő a megbízható felismeréshez.
Mivel a UISwipeGestureRecogniser diszkrét felismerő, nem ütközik a UIPanGestureRecognizer-rel: lassú mozgásnál a pan aktiválódik, gyorsnál — a swipe. Azonban ha UITapGestureRecognizer-rel együtt van ugyanazon a view-n, szükség lehet require(toFail:)-re a tap hamis felismerésének megelőzésére.
Android-ban a swipe felismerésének fő API-ja a GestureDetector az OnGestureListener callback-kel, nevezetesen az onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) metódus. A GestureDetector elemzi az ujj kezdeti és végső pozícióját, a mozgás sebességét a tengelyek mentén és a távolságot, majd a küszöbök túllépésekor meghívja az onFling-et.
A minimális küszöbök ViewConfiguration-on keresztül állíthatók: VelocityTracker.getMinVelocity() (~100 px/s) és ViewConfiguration.getScaledTouchSlop() (~8–16 dp). Az egyedi OnSwipeTouchListener egy elterjedt minta, amely egyszerűsíti az API-t: a fejlesztőnek nem kell manuálisan kiszámítania az irányt és sebességet. Az Android Support Library nem tartalmaz beépített „SwipeDetector”-t, így az egyedi burkoló a szokásos megoldás.
Listákban történő csúsztatáshoz a Google az ItemTouchHelper.SimpleCallback használatát ajánlja a RecyclerView-ból, amely elvonatkoztatja a gesztus detektálását, animációját és az onSwiped() callback-eket. Az IT Sectr-ben egyedi SwipeListener-t használunk ViewPager2-höz és kártya interfészekhez — ez lehetővé teszi a csúsztatás érzékenységének szabályozását a teljesítmény csorbítása nélkül.
Listákhoz (UITableView, RecyclerView) az Apple és a Google speciális API-kat biztosít, amelyek helyettesítik a UISwipeGestureRecognizer kézi hozzáadását. Ezek az API-k támogatják a művelet gombokat, egyedi animációt és a „csúsztass a törléshez” gesztusokat — a mobilalkalmazások szabványos mintáit.
iOS (11+)-ben UISwipeActionsConfiguration használatos: a tableView(_:leadingSwipeActionsConfigurationForRowAt:) metódus UIContextualAction tömböt ad vissza — gombokat címmel, stílussal (destructive, normal) és kezelővel. Például „Törlés” — .destructive piros háttérrel, „Archívum” — .normal szürkével. A rendszer maga animálja a gombok megjelenését és a lenyomás után meghívja a completion blokkot.
Android-ban az ItemTouchHelper.SimpleCallback a RecyclerView-hoz csatlakozik az ItemTouchHelper.attachToRecyclerView()-n keresztül. Paraméterek — irányjelzők (start, end, up, down) és onSwiped(viewHolder, direction) callback. Az onSwiped-en belül adapter.notifyItemRemoved(position) hívódik meg az elem animált eltávolításához. Az ItemTouchHelper automatikusan kezeli a gesztusokat, a görgetéssel (scroll) való ütközéseket és az elem visszaállítását, ha a csúsztatás nem fejeződött be. A Google I/O 2024 szerint az ItemTouchHelper-t az Android-alkalmazások 70%-a használja csúsztatási műveletekkel rendelkező listákban.
UISwipeGestureRecognizer-t ad a view-hoz az előző képernyőre való visszatéréshez. A kód a felismerő minimális konfigurációját mutatja .left iránnyal.
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)
}
}
}
A felismerő a vezérlő root-view-jához kapcsolódik. A navigationController.viewControllers.count ellenőrzése biztosítja, hogy a pop csak akkor hajtódik végre, ha van előző képernyő a veremben. Modális vezérlők esetén a dismiss használatos. A kód nem igényel állapotellenőrzést — a UISwipeGestureRecognizer diszkrét, és az action-t csak sikeres felismeréskor hívja meg.
Egyszerű GestureDetector burkolót valósít meg, amely meghatározza a csúsztatás irányát és meghívja az onSwipeLeft/Right callback-eket.
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() {}
}
Az OnSwipeTouchListener kiterjeszti a SimpleOnGestureListener-t, megvalósítva az onFling-et. A diffX/diffY meghatározza az irányt, a SWIPE_THRESHOLD (100px) és a SWIPE_VELOCITY_THRESHOLD (100 px/s) — küszöbök. Használat: view.setOnTouchListener(OnSwipeTouchListener(context).apply { onSwipeLeft = { dismiss() } }).
Törlés gombot ad hozzá a táblázat cellájának balra csúsztatásakor. A beépített iOS 11+ API-t használja gesztusok kézi felismerése nélkül.
func tableView(
_ tableView: UITableView,
trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath
) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(
style: .destructive,
title: "Törlés"
) { _, _, 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
}
A metódus UISwipeActionsConfiguration-t ad vissza UIContextualAction tömbbel. style: .destructive automatikusan piros hátteret állít be. A performsFirstActionWithFullSwipe = true lehetővé teszi a művelet végrehajtását teljes csúsztatással további nyomás nélkül. Az IT Sectr-ben ezt az API-t használjuk minden műveletekkel rendelkező listához — szabványosított, támogatja a VoiceOver-t és nem igényel egyedi GestureRecognizer-eket.
Gyakran ismételt kérdések
A swipe egy diszkrét gesztus gyors mozgással és ujj felemeléssel, a panorámázás folyamatos húzás koordináta követéssel. A UISwipeGestureRecognizer egyszer aktiválódik, a UIPanGestureRecognizer .began → .changed → .ended eseményeket generál. A választás a forgatókönyvtől függ: swipe — műveletekhez (törlés, lapozás), pan — mozgatáshoz (térkép, csúszka).
A gesztus logikája azonos, de az API eltér. Az iOS a UISwipeGestureRecognizer-t használja direction-nel. Az Android a GestureDetector.onFling()-et használja egyedi küszöbökkel. Az eredmény — ugyanaz az UX eltérő megvalósítással. A cross-platform keretrendszerek (Flutter, React Native) elvonatkoztatják a különbséget egy egységes swipe API-n keresztül.
iOS (11+)-ben használja a UISwipeActionsConfiguration-t a UITableViewDelegate-ban. Android-ban — ItemTouchHelper.SimpleCallback-ot a RecyclerView-hoz. Ezek az API-k helyettesítik a kézi GestureRecognizer-eket, támogatják a művelet gombokat és animációt, helyesen kezelik a görgetéssel való ütközést és alkalmazkodnak a platform HIG irányelveihez.
Összegzés
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is