Gesture Navigation — систем управљања мобилном апликацијом путем сензорних гестова, који је заменио хардверска дугмад на већини модерних паметних телефона. Према Android Developers (2024), гестовна навигација је постала стандард почевши од Android 10, а Apple је прешао на гестове још са iPhone X 2017. Систем укључује swipe, pinch, double tap и long press — сваки гест има одређену намену у контексту екрана. Разумевање архитектуре гестовне навигације неопходно је за стварање интуитивних и одзивних интерфејса.
Главно
Gesture Navigation — метод интеракције корисника са мобилним уређајем путем секвенци додира, покрета и притисака које препознаје сензорни екран. За разлику од традиционалних дугмади, гестови немају фиксни положај на екрану и препознају се по обрасцу покрета: свајп од ивице, пинч са два прста, дуги притисак.
Прелазак на гестовну навигацију почео је са iPhone X (2017), где је Apple потпуно уклонио Home дугме, заменивши га свајпом од доње ивице. Google је следио тренд у Android 10 (2020), нудећи корисницима избор: навигација са три дугмета, навигација са два дугмета и потпуна гестовна навигација. Према StatCounter (2025), преко 75% Android уређаја и 95% iOS уређаја користи гестовну навигацију.
Архитектонски, препознавање гестова се састоји од три фазе: Capture (хватање сензорних догађаја), Recognition (одређивање обрасца покрета) и Action (извршење додељене радње). На системском нивоу, Android и iOS имају уграђене обрађиваче за основне навигационе гестове — свајп назад, прелазак на почетни екран, отварање прекидача апликација. Програмер само треба да правилно интегрише своје гестове у овај систем.
Сви сензорни гестови могу се поделити у три категорије по циљу и начину извођења. Свака врста има своја правила обраде и препоруке за примену у интерфејсу.
Навигациони гестови управљају кретањем између екрана: свајп од леве ивице за повратак (iOS), свајп нагоре за отварање прекидача апликација, свајп од доње ивице за повратак на почетни екран. Ове гестове обрађује систем на нивоу Window и не би требало да буду у конфликту са корисничким гестовима унутар апликације.
Манипулациони гестови мењају положај, величину или оријентацију објеката на екрану. Pinch (скалирање са два прста), Rotate (ротација), Pan (превлачење), Swipe (брзи свајп за листање) — сви ови гестови се обрађују на нивоу View или Composabale и не утичу на системску навигацију.
Контекстуални гестови активирају додатне функције без преласка на други екран. Long press (дуги притисак за контекстуални мени), Double tap (дупли додир за лајк или скалирање), Edge swipe (свајп од ивице за отварање Drawer). Ови гестови захтевају најпажљивију имплементацију, јер се могу преклапати са системским навигационим гестовима.
| Врста геста | Пример | Ниво обраде | Конфликт са системом |
|---|---|---|---|
| Навигациони | Свајп назад | Window / System | Примарни |
| Манипулациони | Pinch zoom | View | Нема |
| Контекстуални | Long press | View | Могућ |
Android SDK пружа вишеслојни систем обраде гестова, почевши од нисконивовских MotionEvent до високонивовских GestureDetector и GestureOverlayView. Правилан избор нивоа зависи од сложености геста и захтева за перформансама.
GestureDetector — високонивовска класа која претвара секвенцу MotionEvent у специфичне гестове: onDown, onShowPress, onSingleTapUp, onScroll, onLongPress, onFling. Програмер преписује потребне методе GestureDetector.SimpleOnGestureListener и добија готов препознати догађај. GestureDetector се препоручује за све стандардне гестове, осим скалирања — за то постоји ScaleGestureDetector.
val gestureDetector = GestureDetector(this, object : GestureDetector.SimpleOnGestureListener() {
override fun onFling(
e1: MotionEvent?, e2: MotionEvent,
velocityX: Float, velocityY: Float
): Boolean {
val deltaX = e2.x - (e1?.x ?: 0f)
return if (Math.abs(deltaX) > Math.abs(e2.y - (e1?.y ?: 0f))) {
if (deltaX > 0) onSwipeRight() else onSwipeLeft()
true
} else false
}
})
view.setOnTouchListener { _, event -> gestureDetector.onTouchEvent(event) }
TouchDelegate — механизам проширења области додира за View. Користи се када је циљни елемент мањи од минималне величине додира од 48dp. На пример, мало дугме „Затвори" у углу екрана добија TouchDelegate који проширује његову област погађања без промене видљиве величине. Google препоручује TouchDelegate за све интерактивне елементе мање од 48x48dp.
Compose пружа модификаторе за обраду гестова: clickable, draggable, swipeable, combinedClickable (за double tap и long press). Изнутра, Compose користи PointerInputScope за нисконивовску обраду, али већини програмера су довољни високонивовски модификатори. За прилагођене гестове користи се pointerInput са awaitPointerEvent.
iOS SDK користи архитектуру UIGestureRecognizer — апстрактну основну класу која анализира секвенцу UITouch и одређује да ли одговара познатом гесту. Apple препоручује коришћење стандардних recognizer свуда где је могуће, а само за јединствене гестове креирање прилагођених подкласа.
UIKit пружа сет готових recognizer: UITapGestureRecognizer, UISwipeGestureRecognizer, UIPanGestureRecognizer, UIPinchGestureRecognizer, UIRotationGestureRecognizer, UILongPressGestureRecognizer. Сваки recognizer има стања (possible, began, changed, ended, cancelled, failed) — програмер прати стање за реакцију у различитим фазама геста.
let swipeBack = UISwipeGestureRecognizer(
target: self,
action: #selector(handleSwipeBack)
)
swipeBack.direction = .right
view.addGestureRecognizer(swipeBack)
@objc func handleSwipeBack() {
navigationController?.popViewController(animated: true)
}
SwiftUI користи декларативне модификаторе гестова, слично Compose: onTapGesture, onLongPressGesture, MagnificationGesture, RotationGesture, DragGesture. SwiftUI аутоматски обрађује конфликте између гестова путем simultaneousGesture, sequencedGesture и exclusiveGesture — модификатора који одређују приоритет гестова при истовременом активирању.
Image("photo")
.gesture(
MagnificationGesture()
.onChanged { scale in
self.currentScale = scale
}
.sequenced(before: DragGesture())
)
InteractivePopGestureRecognizer — системски recognizer који управља свајпом назад у UINavigationController. Подразумевано је активан за све екране осим коренског. Ако ваша апликација користи прилагођени NavigationBar, interactivePopGestureRecognizer може престати да ради — биће потребна његова програмска активација кроз navigationController.interactivePopGestureRecognizer?.delegate.
Конфликт гестова — један од најтежих проблема у гестовној навигацији. Када се кориснички гест (на пример, отварање Drawer свајпом од леве ивице) поклапа са системским гестом (свајп назад на iOS или Android), систем мора да одреди који гест има приоритет. Правилна обрада овог конфликта је критична за UX.
Android 10+ омогућава апликацији да резервише области екрана за своје гестове путем WindowInsets. Користите ViewCompat.setSystemGestureExclusionRects за означавање региона где системски гестови не би требало да раде. На пример, за Drawer са леве стране можете искључити леву ивицу екрана (ширине до 200dp) из системског свајпа назад. Google је поставио лимит: може се искључити до 200dp са сваке стране.
val exclusionRect = Rect(0, 0, 200, height)
ViewCompat.setSystemGestureExclusionRects(
drawerView,
listOf(SystemGestureExclusionRect(exclusionRect))
)
iOS пружа метод gestureRecognizerShouldBegin у UIGestureRecognizerDelegate, који омогућава прилагођеном recognizer-у да одлучи да ли треба да започне препознавање. За Drawer свајп од леве ивице можете проверити положај додира: ако корисник вуче Drawer (растојање веће од threshold), прилагођени гест преузима контролу. Ако гест није препознат, систем враћа контролу InteractivePopGestureRecognizer-у.
Gesture Navigation захтева пажљиво пројектовање, посебно на уређајима са системском гестовном навигацијом. Размотримо честе грешке и препоруке за њихово отклањање.
Најчешћа грешка — постављање интерактивних елемената или имплементација прилагођених свајпова у зонама системских гестова (лева и десна ивица, доња ивица). Корисник покушава да изврши радњу, а уместо тога се активира системска навигација. Увек предвиђајте размаке за системске гестове и обрађујте конфликте кроз exclusion rects.
Параметри гестова (velocity threshold, minimum distance) се подразумевано разликују између платформи. Ако је ваша апликација вишеплатформска, не копирајте параметре са једне платформе на другу — тестирајте сваки гест засебно на Android и iOS. Flutter и React Native аутоматски прилагођавају неке параметре, али не све.
Сваки гест треба да буде праћен визуелном повратном информацијом: промена боје, трансформација, анимација. Корисник мора да разуме да је гест препознат и да се радња извршава. На iOS-у системски recognizer аутоматски дају хаптички фидбек, на Android-у га треба додати кроз HapticFeedbackConstants.
Не могу сви корисници да изводе гестове — особе са ограниченом моториком користе VoiceOver и TalkBack за навигацију. За сваки гест мора постојати дугмадска алтернатива. Google и Apple захтевају да се све гестовне радње дуплирају доступним контролним елементима.
Често постављана питања
iOS — Apple је увео гестовну навигацију са iPhone X 2017. године, заменивши Home дугме свајпом од доње ивице. Android је следио пример у Android 10 (2020), нудећи гестове као алтернативу дугмадима.
Свајп — брзи покрет са високом velocity (пиксела/сек) и прекидима. Скрол — спори покрет са ниском velocity и непрекидан. Користите velocityX/Y за разликовање: праг је обично 500-1000 px/s у зависности од платформе.
Не — Android и iOS не дозвољавају апликацији да искључи системску гестовну навигацију. Можете само резервисати области екрана кроз exclusion rects (Android) или gestureRecognizerShouldBegin (iOS).
Android Emulator подржава мултитач путем Ctrl+клик (додавање другог прста). iOS Simulator — путем Option+клик за два прста. Flutter test користи WidgetTester.timedDrag за симулацију свајпова у unit тестовима.
Gesture War — конфликт између два recognizer-а када оба покушавају да обраде један додир. Избегавајте кроз приоритете: у iOS користите require(toFail:), у Compose — sequentialGesture и exclusiveGesture. Flutter користи GestureArena за аутоматско решавање.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође