Реалізація вібраційної зворотного зв'язку (Haptic Feedback) для мобільної програми
Кнопка нажалась, але користувач не відчув цього — і нажав ще раз. Подвійна відправка форми, подвійний замовлення, подвійний платіж. Haptic feedback — не прикраса інтерфейсу, а механізм підтвердження дії на фізичному рівні.
Чим iOS та Android відрізняються в haptics
На iOS все будується навколо UIFeedbackGenerator та його трьох підклассів: UIImpactFeedbackGenerator для тактильних ударів різної інтенсивності (.light, .medium, .heavy, .rigid, .soft), UISelectionFeedbackGenerator для скролу picker'ів та UINotificationFeedbackGenerator для системних подій (.success, .warning, .error). Генератори потребують явного виклику prepare() перед використанням — без нього вібрація затримається на 150–200 мс, тому що Taptic Engine потребує часу на ініціалізацію. Пропуск prepare() — найчастіша помилка.
З iOS 17 з'явився UICanvasFeedbackGenerator для малювання та CHHapticEngine з Core Haptics для повністю кастомних паттернів: можна задати криву інтенсивності та частоти в часі через CHHapticEvent та CHHapticParameterCurve. Це дозволяє зробити, наприклад, наростаючу вібрацію при довгому нажатті або пульсуючий паттерн для сповіщень.
На Android до API 31 був тільки Vibrator з примітивними паттернами через VibrationEffect.createWaveform(). З Android 12 (API 31) появився VibrationEffect.Composition з предвизначеними примітивами: PRIMITIVE_CLICK, PRIMITIVE_TICK, PRIMITIVE_THUD, PRIMITIVE_SPIN та іншими. Проблема — фрагментація: підтримка конкретних примітивів залежить від виробника та моделі пристрою. Метод Vibrator.areAllPrimitivesSupported() обов'язковий перед використанням. На пристроях без підтримки потрібен graceful fallback на VibrationEffect.createOneShot().
У Flutter — HapticFeedback з flutter/services.dart з методами lightImpact(), mediumImpact(), heavyImpact(), selectionClick(). Для більш тонкого контролю на iOS можна прямо викликати CHHapticEngine через MethodChannel. На Android Flutter використовує Vibrator під капотом, що обмежує можливості на старих API.
У React Native — react-native-haptic-feedback або вбудований Vibration API. Перша бібліотека дає доступ до нативних типів на обох платформах, але потребує перевірки платформи та версії API в runtime.
Типичні помилки реалізації
Haptic без перевірки підтримки. UIFeedbackGenerator мовчки ігнорує виклики на симуляторі, але на пристрої без Taptic Engine (iPad mini 4, старі iPod touch) prepare() та impactOccurred() теж не викликають краш — просто нічого не відбувається. Це очікувана поведінка Apple. На Android — інакше: Vibrator.hasVibrator() та hasAmplitudeControl() потрібно перевіряти явно.
Зловживання haptics в анімаціях. Вібрація при кожному кадрі scroll-анімації убиває батарею та дратує користувача. UISelectionFeedbackGenerator.selectionChanged() повинна викликатися тільки при зміні вибраного елемента, не при кожній зміні offset.
Ігнорування системної настройки. iOS з iOS 13 трансліює зміну «Системна тактильність» через CHHapticEngine, але UIFeedbackGenerator автоматично поважає цю настройку. Кастомні паттерни через CHHapticEngine потребують перевірки CHHapticEngine.capabilitiesForHardware().supportsHaptics та настройки engine.playsHapticsOnly.
Що входить у роботу
Аналізуємо інтерактивні елементи програми: кнопки, свайпи, слайдери, picker'и, pull-to-refresh, drag-and-drop, сповіщення про помилки. Для кожного типу підбираємо інтенсивність та паттерн, відповідний системним гайдлайнам Apple HIG та Material Design 3. Реалізуємо нативні виклики під кожну платформу з fallback-логікою. Тестуємо на реальних пристроях — симулятор iOS не відтворює тактильний відклик коректно.
Якщо потрібні кастомні паттерни (ігрові ефекти, специфічні UI-події), проектуємо CHHapticPattern з кривими інтенсивності та доставляємо через CHHapticPatternPlayer.
Термін: від 1 дня для базової інтеграції стандартних генераторів. Кастомні Core Haptics паттерни та кросплатформенна бібліотека — 2–3 дні.







