Жестова навігація — як влаштовано, типи та реалізація

Автор: IT Sectr Опубліковано: 2026-06-10 Час читання: 10 хв

Жестова навігація — це система керування мобільним застосунком через сенсорні жести, яка замінила апаратні кнопки на більшості сучасних смартфонів. За даними Android Developers (2024), жестова навігація стала стандартом починаючи з Android 10, а Apple перейшла на жести ще з iPhone X у 2017 році. Система включає swipe, pinch, double tap та long press — кожен жест має певне призначення в контексті екрана. Розуміння архітектури жестової навігації необхідне для створення інтуїтивних та чуйних інтерфейсів.

Головне

  • Жестова навігація — керування застосунком через сенсорні жести замість кнопок
  • Три типи жестів: навігаційні, маніпуляційні та контекстні
  • Android 10+ та iOS 7+ використовують жести як системний спосіб навігації
  • GestureDetector — базовий клас обробки жестів у Android View
  • UIGestureRecognizer — абстрактний клас для всіх жестів у iOS UIKit

Що таке Жестова навігація

Жестова навігація — це метод взаємодії користувача з мобільним пристроєм через послідовності дотиків, рухів та натискань, що розпізнаються сенсорним екраном. На відміну від традиційних кнопок, жести не мають фіксованого положення на екрані та розпізнаються за шаблоном руху: свайп від краю, пінч двома пальцями, довге натискання.

Перехід на жестову навігацію розпочався з 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 або Composable і не зачіпають системну навігацію.

Контекстні жести

Контекстні жести активують додаткові функції без переходу на інший екран. Long press (довге натискання для контекстного меню), Double tap (подвійне натискання для лайка або масштабування), Edge swipe (свайп від краю для відкриття Drawer). Ці жести потребують найбільш обережної реалізації, оскільки можуть перетинатися з системними навігаційними жестами.

Тип жестуПрикладРівень обробкиКонфлікт з системою
НавігаційніСвайп назадWindow / SystemПервинний
МаніпуляційніPinch zoomViewНемає
КонтекстніLong pressViewМожливий

Жестова навігація на Android: GestureDetector та MotionEvent

Android SDK надає багаторівневу систему обробки жестів, починаючи від низькорівневих MotionEvent до високорівневих GestureDetector та GestureOverlayView. Правильний вибір рівня залежить від складності жесту та вимог до продуктивності.

GestureDetector — базовий клас

GestureDetector — це високорівневий клас, який перетворює послідовність MotionEvent на конкретні жести: onDown, onShowPress, onSingleTapUp, onScroll, onLongPress, onFling. Розробник перевизначає потрібні методи GestureDetector.SimpleOnGestureListener та отримує готову розпізнану подію. GestureDetector рекомендується для всіх стандартних жестів, крім масштабування — для нього є ScaleGestureDetector.

kotlin
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 для кастомних цілей

TouchDelegate — механізм розширення області дотику для View. Використовується, коли цільовий елемент менший за мінімальний розмір дотику 48dp. Наприклад, маленька кнопка «Закрити» в кутку екрана отримує TouchDelegate, що розширює її hit area без зміни видимого розміру. Google рекомендує TouchDelegate для всіх інтерактивних елементів менше 48x48dp.

Gesture в Jetpack Compose

Compose надає модифікатори для обробки жестів: clickable, draggable, swipeable, combinedClickable (для double tap та long press). Всередині Compose використовує PointerInputScope для низькорівневої обробки, але більшості розробників достатньо високорівневих модифікаторів. Для кастомних жестів використовується pointerInput з awaitPointerEvent.

Жестова навігація на iOS: UIGestureRecognizer та SwiftUI

iOS SDK використовує архітектуру UIGestureRecognizer — абстрактного базового класу, який аналізує послідовність UITouch та визначає, чи відповідає вона відомому жесту. Apple рекомендує використовувати стандартні recognizer всюди, де можливо, і тільки для унікальних жестів створювати кастомні підкласи.

UIGestureRecognizer в UIKit

UIKit надає набір готових recognizer: UITapGestureRecognizer, UISwipeGestureRecognizer, UIPanGestureRecognizer, UIPinchGestureRecognizer, UIRotationGestureRecognizer, UILongPressGestureRecognizer. Кожен recognizer має states (possible, began, changed, ended, cancelled, failed) — розробник відстежує стан для реакції на різних етапах жесту.

swift
let swipeBack = UISwipeGestureRecognizer(
    target: self,
    action: #selector(handleSwipeBack)
)
swipeBack.direction = .right
view.addGestureRecognizer(swipeBack)

@objc func handleSwipeBack() {
    navigationController?.popViewController(animated: true)
}

Gesture в SwiftUI

SwiftUI використовує декларативні модифікатори жестів, аналогічно Compose: onTapGesture, onLongPressGesture, MagnificationGesture, RotationGesture, DragGesture. SwiftUI автоматично обробляє конфлікти між жестами через simultaneousGesture, sequencedGesture та exclusiveGesture — модифікатори, що визначають пріоритет жестів при одночасному спрацьовуванні.

swift
Image("photo")
    .gesture(
        MagnificationGesture()
            .onChanged { scale in
                self.currentScale = scale
            }
            .sequenced(before: DragGesture())
    )

InteractivePopGestureRecognizer

InteractivePopGestureRecognizer — системний recognizer, що керує свайпом назад в UINavigationController. За замовчуванням він активний для всіх екранів, крім кореневого. Якщо ваш застосунок використовує кастомний NavigationBar, interactivePopGestureRecognizer може перестати працювати — знадобиться його програмна активація через navigationController.interactivePopGestureRecognizer?.delegate.

Конфлікт системних та користувацьких жестів

Конфлікт жестів — одна з найскладніших проблем у gesture navigation. Коли користувацький жест (наприклад, відкриття Drawer свайпом від лівого краю) збігається з системним жестом (свайп назад на iOS або Android), система повинна визначити, який жест має пріоритет. Правильна обробка цього конфлікту критична для UX.

Рішення на Android: Insets та SystemGestureExclusionRects

Android 10+ дозволяє застосунку зарезервувати області екрана для своїх жестів через WindowInsets. Використовуйте ViewCompat.setSystemGestureExclusionRects для вказання регіонів, де системні жести не повинні спрацьовувати. Наприклад, для Drawer зліва можна виключити лівий край екрана (шириною до 200dp) із системного свайпу назад. Google встановила ліміт: можна виключити до 200dp по кожній стороні.

kotlin
val exclusionRect = Rect(0, 0, 200, height)
ViewCompat.setSystemGestureExclusionRects(
    drawerView,
    listOf(SystemGestureExclusionRect(exclusionRect))
)

Рішення на iOS: UIGestureRecognizerDelegate

iOS надає метод gestureRecognizerShouldBegin в UIGestureRecognizerDelegate, який дозволяє кастомному recognizer вирішити, чи повинен він почати розпізнавання. Для Drawer свайпу від лівого краю можна перевірити положення дотику: якщо користувач тягне Drawer (відстань більше threshold), кастомний жест перехоплює керування. Якщо жест не розпізнано, система повертає керування InteractivePopGestureRecognizer.

Типові помилки та best practices

Жестова навігація потребує уважного проєктування, особливо на пристроях із системною жестовою навігацією. Розглянемо часті помилки та рекомендації щодо їх усунення.

Помилка: ігнорування зон конфлікту біля країв екрана

Найпоширеніша помилка — розміщення інтерактивних елементів або реалізація кастомних свайпів у зонах системних жестів (лівий та правий краї, нижній край). Користувач намагається виконати дію, а замість цього спрацьовує системна навігація. Завжди передбачайте відступи для системних жестів та обробляйте конфлікти через exclusion rects.

Помилка: різна швидкість розпізнавання на Android та iOS

Параметри жестів (velocity threshold, minimum distance) за замовчуванням відрізняються між платформами. Якщо ваш застосунок кросплатформний, не копіюйте параметри з однієї платформи на іншу — тестуйте кожен жест окремо на Android та iOS. Flutter та React Native автоматично адаптують деякі параметри, але не всі.

Best Practice: візуальний зворотний зв'язок

Кожен жест повинен супроводжуватися візуальним зворотним зв'язком: зміна кольору, трансформація, анімація. Користувач повинен розуміти, що жест розпізнано і дія виконується. На iOS системні recognizer автоматично дають haptic feedback, на Android його потрібно додавати через HapticFeedbackConstants.

Best Practice: accessibility для жестів

Не всі користувачі можуть виконувати жести — люди з обмеженою моторикою використовують VoiceOver та TalkBack для навігації. Для кожного жесту повинна бути кнопкова альтернатива. Google та Apple вимагають, щоб всі жестові дії дублювалися доступними для accessibility елементами керування.

Часто задавані питання

Яка платформа першою впровадила жестову навігацію?

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 та як його уникнути?

Gesture War — конфлікт між двома recognizer, коли обидва намагаються обробити один дотик. Уникайте через пріоритети: в iOS використовуйте require(toFail:), в Compose — sequentialGesture та exclusiveGesture. Flutter використовує GestureArena для автоматичного вирішення.

Підсумки

  • Жестова навігація — керування застосунком через сенсорні жести, що стала стандартом на Android 10+ та iOS 7+
  • Три категорії жестів: навігаційні (свайпи), маніпуляційні (pinch, rotate) та контекстні (long press)
  • GestureDetector на Android та UIGestureRecognizer на iOS — базові класи обробки жестів
  • Jetpack Compose та SwiftUI надають декларативні модифікатори для всіх стандартних жестів
  • Конфлікт жестів вирішується через exclusion rects (Android) та gestureRecognizerShouldBegin (iOS)
  • Візуальний зворотний зв'язок та accessibility — обов'язкові вимоги для жестової навігації
  • Параметри жестів відрізняються між платформами — не копіюйте threshold та velocity напряму

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також