Swipe: چیست، پردازش سوایپ‌ها در توسعه موبایل

نویسنده: IT Sectr منتشر شده: 2026-02-27 زمان مطالعه: 8 دقیقه
Swipe (سوایپ) — یک ژست گسسته است که کاربر انگشت خود را در یک جهت روی صفحه میکشد — راست، چپ، بالا یا پایین. برخلاف کشیدن (drag)، سوایپ حرکت پیوسته را ردیابی نمیکند: پس از عبور از آستانه حداقل و جدا شدن انگشت از صفحه، به عنوان یک عمل کامل تشخیص داده میشود. بر اساس تحقیقات UX Nielsen Norman Group (2024)، سوایپ دومین ژست پرتکرار پس از ضربه زدن (tap) در برنامه‌های موبایل است که در 23% تعاملات کاربر استفاده میشود.

نکات اصلی

  • Swipe — ژست گسسته: پس از عبور از آستانه و جدا شدن انگشت به عنوان یک عمل کامل تشخیص داده میشود.
  • در iOS پردازش سوایپ از طریق UISwipeGestureRecognizer با تنظیم جهت (direction) و تعداد انگشتان انجام میشود.
  • در Android از GestureDetector با onFling(MotionEvent) یا OnSwipeTouchListener برای API ساده‌شده استفاده میشود.
  • آستانه سوایپ — ~20px در iOS (viewConfiguration) و از طریق VelocityTracker در Android قابل تنظیم است.
  • برای لیست‌ها (UITableView/RecyclerView) از مکانیزم‌های داخلی — UISwipeActionsConfiguration و ItemTouchHelper — به جای تشخیص دستی استفاده میشود.

سوایپ چیست؟

سوایپ — حرکت سریع لغزشی انگشت روی سطح صفحه است که با جدا شدن پایان می‌یابد. سوایپ می‌تواند کوتاه (پیمایش عنصر) یا بلند (باز کردن پرده) باشد، اما ویژگی کلیدی — گسستگی: سیستم آن را به عنوان یک رویداد واحد تشخیص می‌دهد، نه دنباله‌ای پیوسته از مختصات.

سیستم‌عامل‌های موبایل سوایپ را بر اساس سه پارامتر تعیین می‌کنند: حداقل فاصله (آستانه)، حداقل سرعت (velocity) و جهت. اگر انگشت به آرامی حرکت کند یا فاصله کافی نباشد، سیستم ژست را به عنوان پانوراما (pan) یا ضربه (tap) تفسیر می‌کند. مقادیر آستانه بین پلتفرم‌ها متفاوت است: iOS از ثابت UISwipeGestureRecognizer با آستانه ثابت استفاده می‌کند، Android — ViewConfiguration.getScaledTouchSlop() که بسته به تراکم صفحه ~8–16 dp برمی‌گرداند.

بر اساس Android Developers Documentation، onFling (سوایپ) در GestureDetector با سرعت بالای 100 px/s و فاصله از 50px فعال می‌شود. در IT Sectr ما از سوایپ برای ناوبری (گالری‌ها، رابط‌های کارتی، آموزش) استفاده می‌کنیم — این ژست برای کاربران در هر سنی بصری و قابل فهم است.

سوایپ در مقابل پانوراما: تفاوت چیست؟

سوایپ و پانوراما (pan/drag) — انواع مختلفی از ژست‌ها هستند، اگرچه هر دو از حرکت انگشت روی صفحه استفاده می‌کنند. سوایپ گسسته است و به معنای „یک عمل انجام بده” است، در حالی که پانوراما پیوسته است و به معنای „شیء را تا زمانی که انگشت روی صفحه است حرکت بده” می‌باشد.

پارامتر سوایپ (Swipe) پانوراما (Pan/Drag)
نوع گسسته پیوسته
رویدادها یک (تشخیص/عدم تشخیص) چندتایی (.began → .changed → .ended)
سرعت زیاد (حرکت سریع) هرگونه (حرکت آهسته)
مثال iOS UISwipeGestureRecognizer UIPanGestureRecognizer
مثال Android GestureDetector.onFling() GestureDetector.onScroll()
سناریو حذف ایمیل، ورق زدن صفحه جابجایی نقشه، کشیدن فایل
ردیابی مختصات خیر (فقط جهت) بله (به‌روزرسانی مداوم مختصات)

انتخاب بین سوایپ و پانوراما به وظیفه بستگی دارد. برای اقدامات روی عنصر (حذف، بایگانی، باز کردن منو) از سوایپ استفاده کنید. برای دستکاری مستقیم (جابجایی، بزرگنمایی) — پانوراما. ترکیب ژست‌ها روی یک عنصر نیاز به require(toFail:) یا منطق سفارشی دارد.

سوایپ در iOS: UISwipeGestureRecognizer

UISwipeGestureRecognizer — زیرکلاس UIGestureRecognizer که سوایپ گسسته را در یکی از چهار جهت تشخیص می‌دهد. برخلاف UIPanGestureRecognizer، رویدادهای میانی .changed تولید نمی‌کند: هنگام تشخیص، action دقیقاً یک بار فراخوانی می‌شود.

ویژگی direction (UISwipeGestureRecognizer.Direction) جهت ردیابی شده را تعیین می‌کند — .left, .right, .up, .down. می‌توان از طریق ماسک ترکیب کرد: برای سوایپ‌های افقی [.left, .right]. ویژگی numberOfTouchesRequired تعداد انگشتان را تعیین می‌کند — پیش‌فرض ۱. UISwipeGestureRecognizer آستانه فاصله قابل تنظیمی ندارد — iOS از مقدار داخلی حدود 20px استفاده می‌کند که برای تشخیص قابل اطمینان کافی است.

از آنجایی که UISwipeGestureRecogniser یک تشخیص‌دهنده گسسته است، با UIPanGestureRecognizer تداخل ندارد: در حرکت آهسته pan فعال می‌شود، در حرکت سریع — swipe. با این حال در هم‌زیستی با UITapGestureRecognizer روی یک view ممکن است برای جلوگیری از تشخیص نادرست ضربه، require(toFail:) مورد نیاز باشد.

سوایپ در Android: GestureDetector

در Android API اصلی برای تشخیص سوایپ GestureDetector با بازخورد OnGestureListener است، دقیقاً متد onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY). GestureDetector موقعیت اولیه و نهایی انگشت، سرعت حرکت در امتداد محورها و فاصله را تحلیل می‌کند، سپس در صورت تجاوز از آستانه‌ها onFling را فراخوانی می‌کند.

آستانه‌های حداقل از طریق ViewConfiguration تنظیم می‌شوند: VelocityTracker.getMinVelocity() (~100 px/s) و ViewConfiguration.getScaledTouchSlop() (~8–16 dp). OnSwipeTouchListener سفارشی — الگوی رایجی است که API را ساده می‌کند: توسعه‌دهنده نیازی به محاسبه دستی جهت و سرعت ندارد. Android Support Library شامل „SwipeDetector” داخلی نیست، بنابراین پوشش سفارشی — راه‌حل استاندارد است.

برای سوایپ در لیست‌ها Google استفاده از ItemTouchHelper.SimpleCallback از RecyclerView را توصیه می‌کند که تشخیص ژست، انیمیشن و بازخوردهای onSwiped() را انتزاع می‌کند. در IT Sectr ما از SwipeListener سفارشی برای ViewPager2 و رابط‌های کارتی استفاده می‌کنیم — این کنترل حساسیت سوایپ را بدون آسیب به عملکرد فراهم می‌کند.

سوایپ در لیست‌ها: SwipeActions و ItemTouchHelper

برای لیست‌ها (UITableView, RecyclerView) Apple و Google API‌های تخصصی ارائه می‌دهند که جایگزین افزودن دستی UISwipeGestureRecognizer می‌شوند. این API‌ها دکمه‌های اقدام، انیمیشن سفارشی و ژست‌های „بکشید تا حذف شود” را پشتیبانی می‌کنند — الگوهای استاندارد برنامه‌های موبایل.

در iOS (11+) از UISwipeActionsConfiguration استفاده می‌شود: متد tableView(_:leadingSwipeActionsConfigurationForRowAt:) آرایه‌ای از UIContextualAction — دکمه‌هایی با عنوان، سبک (destructive, normal) و گرداننده برمی‌گرداند. مثلاً „حذف” — .destructive با پس‌زمینه قرمز، „بایگانی” — .normal با خاکستری. سیستم خود ظاهر شدن دکمه‌ها را انیمیشن می‌کند و پس از فشار دادن بلوک completion را فراخوانی می‌کند.

در Android ItemTouchHelper.SimpleCallback از طریق ItemTouchHelper.attachToRecyclerView() به RecyclerView متصل می‌شود. پارامترها — پرچم‌های جهت (start, end, up, down) و بازخورد onSwiped(viewHolder, direction). در داخل onSwiped برای حذف عنصر با انیمیشن، adapter.notifyItemRemoved(position) فراخوانی می‌شود. ItemTouchHelper به طور خودکار ژست‌ها، تداخل با پیمایش (scroll) و بازگشت عنصر را در صورت کامل نشدن سوایپ مدیریت می‌کند. بر اساس Google I/O 2024، ItemTouchHelper در 70% برنامه‌های Android با اقدامات سوایپ در لیست‌ها استفاده می‌شود.

نمونه کد در Swift و Kotlin

مثال ۱: سوایپ به چپ در iOS (Swift)

UISwipeGestureRecognizer را به view برای بازگشت به صفحه قبلی اضافه می‌کند. کد پیکربندی حداقل تشخیص‌دهنده با جهت .left را نشان می‌دهد.

swift
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)
        }
    }
}

تشخیص‌دهنده به root-view کنترلر متصل می‌شود. بررسی navigationController.viewControllers.count تضمین می‌کند که pop فقط در صورت وجود صفحه قبلی در پشته انجام می‌شود. برای کنترلرهای مودال از dismiss استفاده می‌شود. کد نیاز به بررسی state ندارد — UISwipeGestureRecognizer گسسته است و action را فقط در تشخیص موفق فراخوانی می‌کند.

مثال ۲: سوایپ در Android (Kotlin) با OnSwipeTouchListener سفارشی

یک پوشش ساده GestureDetector را پیاده‌سازی می‌کند که جهت سوایپ را تعیین می‌کند و بازخوردهای onSwipeLeft/Right را فراخوانی می‌کند.

kotlin
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 را با پیاده‌سازی onFling گسترش می‌دهد. diffX/diffY جهت را تعیین می‌کنند، SWIPE_THRESHOLD (100px) و SWIPE_VELOCITY_THRESHOLD (100 px/s) — آستانه‌ها. استفاده: view.setOnTouchListener(OnSwipeTouchListener(context).apply { onSwipeLeft = { dismiss() } }).

مثال ۳: SwipeActions در iOS (UITableView)

دکمه حذف را هنگام سوایپ به چپ روی سلول جدول اضافه می‌کند. از API داخلی iOS 11+ بدون تشخیص دستی ژست استفاده می‌کند.

swift
func tableView(
    _ tableView: UITableView,
    trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath
) -> UISwipeActionsConfiguration? {
    let deleteAction = UIContextualAction(
        style: .destructive,
        title: "حذف"
    ) { _, _, 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
}

متد UISwipeActionsConfiguration با آرایه‌ای از UIContextualAction برمی‌گرداند. style: .destructive به طور خودکار پس‌زمینه قرمز تنظیم می‌کند. performsFirstActionWithFullSwipe = true امکان اجرای عمل با سوایپ کامل بدون فشار اضافی را فراهم می‌کند. در IT Sectr ما از این API برای تمام لیست‌های دارای اقدام استفاده می‌کنیم — استاندارد شده است، از VoiceOver پشتیبانی می‌کند و نیاز به GestureRecognizer سفارشی ندارد.

سوالات متداول

چگونه سوایپ را از پانوراما تشخیص دهیم؟

سوایپ — ژست گسسته با حرکت سریع و جدا شدن انگشت، پانوراما — کشیدن پیوسته با ردیابی مختصات. UISwipeGestureRecognizer یک بار فعال می‌شود، UIPanGestureRecognizer .began → .changed → .ended تولید می‌کند. انتخاب بستگی به سناریو دارد: سوایپ — برای اقدامات (حذف، ورق زدن)، pan — برای جابجایی (نقشه، اسلایدر).

آیا سوایپ در iOS و Android یکسان کار می‌کند؟

منطق ژست یکسان است، اما API متفاوت است. iOS از UISwipeGestureRecognizer با direction استفاده می‌کند. Android از GestureDetector.onFling() با آستانه‌های سفارشی استفاده می‌کند. نتیجه — UX یکسان با پیاده‌سازی متفاوت. فریم‌ورک‌های چندپلتفرمی (Flutter, React Native) تفاوت را از طریق API واحد سوایپ انتزاع می‌کنند.

چگونه سوایپ را در لیست مدیریت کنیم؟

در iOS (11+) از UISwipeActionsConfiguration در UITableViewDelegate استفاده کنید. در Android — ItemTouchHelper.SimpleCallback برای RecyclerView. این API‌ها جایگزین GestureRecognizer دستی می‌شوند، دکمه‌های اقدام و انیمیشن را پشتیبانی می‌کنند، تداخل با پیمایش را به درستی مدیریت می‌کنند و با HIG پلتفرم تطبیق می‌یابند.

خلاصه

  • سوایپ — ژست گسسته لغزش سریع انگشت، دومین از نظر تکرار پس از ضربه (۲۳٪ تعاملات).
  • در iOS UISwipeGestureRecogniser سوایپ‌ها را در چهار جهت با آستانه ثابت ~20px پردازش می‌کند.
  • در Android GestureDetector.onFling() با آستانه‌های سفارشی سرعت و فاصله استفاده می‌شود.
  • برای لیست‌ها به جای تشخیص‌دهنده‌های دستی از UISwipeActionsConfiguration (iOS) و ItemTouchHelper (Android) استفاده کنید.
  • سوایپ با گسستگی و سرعت بالا از پانوراما متفاوت است — این ژست‌ها را در طراحی اشتباه نگیرید.
  • OnSwipeTouchListener سفارشی در Android با پنهان کردن محاسبه جهت، API GestureDetector را ساده می‌کند.
  • در IT Sectr ما از سوایپ برای ناوبری، حذف عناصر و آموزش استفاده می‌کنیم — ژست بصری است و نیاز به یادگیری ندارد.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید