Asosiy ma'lumotlar
Swipe — barmoqning ekran yuzasida tez sirpanish harakati bo'lib, uzilish bilan tugaydi. Swipe qisqa (elementni aylantirish) yoki uzun (pardani ochish) bo'lishi mumkin, ammo asosiy xususiyat — diskretlik: tizim uni bitta voqea sifatida tan oladi, koordinatalarning uzluksiz ketma-ketligi sifatida emas.
Mobil OTlar surishni uch parametr bo'yicha aniqlaydi: minimal masofa (chegara), minimal tezlik (velocity) va yo'nalish. Agar barmoq sekin harakatlansa yoki masofa yetarli bo'lmasa, tizim jestni panoramlash (pan) yoki tap sifatida talqin qiladi. Chegara qiymatlari platformalar orasida farqlanadi: iOS sobit chegarali UISwipeGestureRecognizer doimiysidan foydalanadi, Android — ViewConfiguration.getScaledTouchSlop(), ekran zichligiga qarab ~8–16 dp qaytaradi.
Android Developers Documentation ga ko'ra, GestureDetector dagi onFling (swipe) 100 px/s dan yuqori tezlikda va 50px masofadan ishga tushadi. IT Sectr da biz surishni navigatsiya uchun ishlatamiz (galereyalar, kartali interfeyslar, onboarding) — bu jest har qanday yoshdagi foydalanuvchilar uchun intuitivdir.
Swipe va panoramlash (pan/drag) — har xil jest turlari, ikkalasi ham barmoqning ekranda harakatlanishidan foydalansa ham. Swipe diskret va „bitta harakatni bajar” degan ma'noni anglatadi, panoramlash esa uzluksiz va „barmoq ekranda ekan, obyektni harakatlantir” degan ma'noni anglatadi.
| Parametr | Swipe | Panoramlash (Pan/Drag) |
|---|---|---|
| Tur | Diskret | Uzluksiz |
| Voqealar | Bitta (tan olingan/tan olinmagan) | Ko'p (.began → .changed → .ended) |
| Tezlik | Yuqori (tez harakat) | Har qanday (sekin harakat) |
| iOS misol | UISwipeGestureRecognizer | UIPanGestureRecognizer |
| Android misol | GestureDetector.onFling() | GestureDetector.onScroll() |
| Ssenariy | Xatni o'chirish, sahifani aylantirish | Xaritani ko'chirish, faylni sudrash |
| Koordinatalarni kuzatish | Yo'q (faqat yo'nalish) | Ha (doimiy koordinata yangilash) |
Swipe va panoramlash o'rtasidagi tanlov vazifaga bog'liq. Element bilan harakatlar uchun (o'chirish, arxivlash, menyu ochish) surishdan foydalaning. To'g'ridan-to'g'ri manipulyatsiya uchun (ko'chirish, masshtablash) — panoramlash. Bir elementda jestlarni aralashtirish require(toFail:) yoki maxsus mantiqni talab qiladi.
UISwipeGestureRecognizer — to'rt yo'nalishdan birida diskret surishni tanib oluvchi UIGestureRecognizer pastki sinfi. UIPanGestureRecognizer dan farqli o'laroq, oraliq .changed voqealarini yaratmaydi: tanib olishda action aniq bir marta chaqiriladi.
Direction xususiyati (UISwipeGestureRecognizer.Direction) kuzatiladigan yo'nalishni belgilaydi — .left, .right, .up, .down. Niqob orqali birlashtirish mumkin: gorizontal surishlar uchun [.left, .right]. numberOfTouchesRequired xususiyati barmoqlar sonini belgilaydi — sukut bo'yicha 1. UISwipeGestureRecognizer sozlanishi masofa chegarasiga ega emas — iOS ishonchli tanib olish uchun taxminan 20px o'rnatilgan qiymatdan foydalanadi.
UISwipeGestureRecogniser diskret tanib oluvchi bo'lgani uchun UIPanGestureRecognizer bilan ziddiyatga kirmaydi: sekin harakatda pan, tez harakatda swipe ishlaydi. Biroq bir view da UITapGestureRecognizer bilan birga mavjud bo'lganda, tapning yolg'on tanib olinishining oldini olish uchun require(toFail:) talab qilinishi mumkin.
Android da surishni tanib olish uchun asosiy API GestureDetector OnGestureListener callback i bilan, aniqrog'i onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) metodi. GestureDetector barmoqning boshlang'ich va oxirgi holatini, o'qlar bo'yicha harakat tezligini va masofani tahlil qiladi, so'ngra chegaralardan oshganda onFling ni chaqiradi.
Minimal chegaralar ViewConfiguration orqali sozlanadi: VelocityTracker.getMinVelocity() (~100 px/s) va ViewConfiguration.getScaledTouchSlop() (~8–16 dp). Maxsus OnSwipeTouchListener — API ni soddalashtiradigan keng tarqalgan naqsh: dasturchi qo'lda yo'nalish va tezlikni hisoblashi shart emas. Android Support Library o'rnatilgan „SwipeDetector” ni o'z ichiga olmaydi, shuning uchun maxsus o'rash — standart yechim.
Ro'yxatlarda surish uchun Google RecyclerView dan ItemTouchHelper.SimpleCallback dan foydalanishni tavsiya qiladi, u jest deteksiyasini, animatsiyani va onSwiped() callback larini abstraktsiyalashtiradi. IT Sectr da biz ViewPager2 va kartali interfeyslar uchun maxsus SwipeListener dan foydalanamiz — bu ishlashga zarar yetkazmasdan surish sezgirligi ustidan nazorat beradi.
Ro'yxatlar uchun (UITableView, RecyclerView) Apple va Google ixtisoslashgan API larni taqdim etadi, UISwipeGestureRecognizer ni qo'lda qo'shish o'rnini bosadi. Bu API lar harakat tugmalarini, maxsus animatsiyani va „o'chirish uchun suring” jestlarini qo'llab-quvvatlaydi — mobil ilovalarning standart naqshlari.
iOS (11+) da UISwipeActionsConfiguration ishlatiladi: tableView(_:leadingSwipeActionsConfigurationForRowAt:) metodi sarlavhali, stilli (destructive, normal) va handler li UIContextualAction massivini qaytaradi. Masalan, „O'chirish” — qizil fon bilan .destructive, „Arxiv” — kulrang bilan .normal. Tizim tugmalarning paydo bo'lishini animatsiya qiladi va bosilgandan so'ng completion blokini chaqiradi.
Android da ItemTouchHelper.SimpleCallback RecyclerView ga ItemTouchHelper.attachToRecyclerView() orqali biriktiriladi. Parametrlar — yo'nalish bayroqlari (start, end, up, down) va onSwiped(viewHolder, direction) callback i. onSwiped ichida elementni animatsiya bilan o'chirish uchun adapter.notifyItemRemoved(position) chaqiriladi. ItemTouchHelper avtomatik ravishda jestlarni, aylantirish bilan ziddiyatlarni va surish tugallanmasa elementni qaytarishni boshqaradi. Google I/O 2024 ma'lumotlariga ko'ra, ItemTouchHelper ro'yxatlarda surish harakatlari bo'lgan Android ilovalarining 70% ida ishlatiladi.
Oldingi ekranga qaytish uchun view ga UISwipeGestureRecognizer qo'shadi. Kod .left yo'nalishi bilan tanib oluvchining minimal konfiguratsiyasini ko'rsatadi.
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)
}
}
}
Tanib oluvchi kontrollerning root view iga biriktiriladi. navigationController.viewControllers.count tekshiruvi pop faqat stackda oldingi ekran mavjud bo'lganda bajarilishini kafolatlaydi. Modal kontrollerlar uchun dismiss ishlatiladi. Kod state tekshiruvini talab qilmaydi — UISwipeGestureRecognizer diskret va action ni faqat muvaffaqiyatli tanib olishda chaqiradi.
GestureDetector ning oddiy o'ramini amalga oshiradi, surish yo'nalishini aniqlaydi va onSwipeLeft/Right callback larini chaqiradi.
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 SimpleOnGestureListener ni kengaytiradi, onFling ni amalga oshiradi. diffX/diffY yo'nalishni aniqlaydi, SWIPE_THRESHOLD (100px) va SWIPE_VELOCITY_THRESHOLD (100 px/s) — chegaralar. Foydalanish: view.setOnTouchListener(OnSwipeTouchListener(context).apply { onSwipeLeft = { dismiss() } }).
Jadval katakchasini chapga surishda o'chirish tugmasini qo'shadi. Jestlarni qo'lda tanib olmasdan iOS 11+ o'rnatilgan API sini ishlatadi.
func tableView(
_ tableView: UITableView,
trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath
) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(
style: .destructive,
title: "O'chirish"
) { _, _, 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
}
Metod UIContextualAction massivi bilan UISwipeActionsConfiguration qaytaradi. style: .destructive avtomatik qizil fonni o'rnatadi. performsFirstActionWithFullSwipe = true qo'shimcha bosmasdan to'liq surish bilan harakatni bajarishga imkon beradi. IT Sectr da biz bu API ni barcha harakat ro'yxatlari uchun ishlatamiz — standartlashtirilgan, VoiceOver ni qo'llab-quvvatlaydi va maxsus GestureRecognizer larni talab qilmaydi.
Ko'p beriladigan savollar
Swipe — diskret jest tez harakat va barmoq uzilishi bilan, panoramlash — koordinatalarni kuzatish bilan uzluksiz sudrash. UISwipeGestureRecognizer bir marta ishga tushadi, UIPanGestureRecognizer .began → .changed → .ended yaratadi. Tanlov ssenariyga bog'liq: swipe — harakatlar uchun (o'chirish, aylantirish), pan — ko'chirish uchun (xarita, slayder).
Jest mantig'i bir xil, ammo API farqlanadi. iOS UISwipeGestureRecognizer direction bilan ishlatadi. Android maxsus chegaralar bilan GestureDetector.onFling() ni ishlatadi. Natija — turli amalga oshirishda bir xil UX. O'zaro platforma freymvorklari (Flutter, React Native) farqni yagona surish API si orqali abstraktsiyalashtiradi.
iOS (11+) da UITableViewDelegate da UISwipeActionsConfiguration dan foydalaning. Android da — RecyclerView uchun ItemTouchHelper.SimpleCallback. Bu API lar qo'lda GestureRecognizer larni almashtiradi, harakat tugmalari va animatsiyani qo'llab-quvvatlaydi, aylantirish bilan ziddiyatni to'g'ri boshqaradi va platforma HIG lariga moslashadi.
Xulosalar
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.