Tap — ژست پایه رابطهای لمسی: ضربه زدن یکباره با انگشت به صفحه و سپس رها کردن. Tap عمل اصلی (primary action) در سیستمعاملهای موبایل است — باز کردن برنامهها، فشار دادن دکمهها، انتخاب آیتمهای لیست. در 100–300 میلیثانیه تشخیص داده میشود و رویداد کلیک را تولید میکند. در iOS از طریق UITapGestureRecognizer و در Android از طریق setOnClickListener یا View.onClick پردازش میشود.
نکات اصلی
Tap (ضربه، فشار) — ژست ضربه سریع انگشت یا قلم به صفحه لمسی. ژست از دو فاز تشکیل شده است: لمس (touch down) و رها کردن (touch up) که در یک مکان بدون جابجایی انجام میشوند. سیستم Tap را زمانی تشخیص میدهد که فاصله زمانی بین down و up از مقدار آستانه (معمولاً 300–500 میلیثانیه) تجاوز نکند. اگر کاربر انگشت را بیشتر نگه دارد — ژست به Long Press تبدیل میشود.
Tap — اساس UX موبایل. در همه پلتفرمهای موبایل، Tap جایگزین کلیک چپ ماوس در رابطهای دسکتاپ میشود. برخلاف کلیک ماوس، Tap اصلاحکننده (Shift+کلیک، Ctrl+کلیک) و hover ندارد — این محدودیت طراحی رابطهای موبایل را شکل میدهد. برای جبران عدم پیشنمایش، پلتفرمهای موبایل از بازخورد بصری استفاده میکنند: highlight در هنگام لمس، افکت ripple در Android، تغییر شفافیت در iOS.
آناتومی Tap شامل پنج مرحله در سطح سیستم است: بیدار شدن سنسور (لمس)، تعیین مختصات، فیلتر نویز (انگشت نباید بیش از فاصله آستانه جابجا شود)، انتظار برای پایان (رها کردن یا نگه داشتن)، طبقهبندی (Tap، Long Press، Drag). کنترلرهای لمسی مدرن این چرخه را در 8–16 میلیثانیه با فرکانس پرسوجوی 60–120 هرتز پردازش میکنند.
Tap و Click — رویدادهای متفاوت با فیزیک متفاوت. Click — رویداد ماوس که هنگام فشار دادن و رها کردن دکمه ماوس در یک موقعیت رخ میدهد. Tap — رویداد صفحه لمسی که هنگام لمس انگشت رخ میدهد. در دستگاههای موبایل، مرورگر Tap را با تأخیر 300–350 میلیثانیه به رویداد click تبدیل میکند (برای شبیهسازی ضربه دوگانه برای بزرگنمایی). این تأخیر از نظر تاریخی مشکل وب موبایل بود، تا زمانی که Apple و Google meta viewport را با user-scalable=no معرفی کردند.
| پارامتر | Tap (لمسی) | Click (ماوس) |
|---|---|---|
| دستگاه ورودی | انگشت، قلم | مکاننمای ماوس |
| فازها | touchstart → touchend | mousedown → mouseup |
| پیشنمایش (hover) | ندارد | دارد (hover) |
| تأخیر | 0–500 میلیثانیه | 0 میلیثانیه |
| دقت | پایین (انگشت پهنتر از مکاننما) | بالا (پیکسلی) |
| اصلاحکنندهها | ندارد | Shift، Ctrl، Cmd |
| چندگانه | مولتیتاچ (2+ انگشت) | ندارد (یک مکاننما) |
Touch Events — API جداگانه از Mouse Events است. رویدادهای لمسی (touchstart، touchmove، touchend) آرایهای از نقاط لمس (TouchList)، مختصات، نیروی فشار (pressure) و اندازه ناحیه لمس (radiusX، radiusY) را منتقل میکنند. Mouse Events فقط مختصات مکاننما را منتقل میکند. مرورگرهای مدرن click را از touchend میسازند، اگر حرکت انگشت و رویداد touchcancel وجود نداشته باشد. Pointer Events API هر دو رویکرد را ترکیب میکند و پردازش یکپارچه همه دستگاههای ورودی را فراهم میکند.
UITapGestureRecognizer — تشخیصدهنده استاندارد Tap تکی و چندگانه در iOS SDK. از پیکربندی numberOfTapsRequired (تعداد ضربههای متوالی) و numberOfTouchesRequired (تعداد انگشتان همزمان لمسکننده) پشتیبانی میکند. تشخیصدهنده زمانی به حالت UIGestureRecognizerStateRecognized میرود که کاربر انگشت را رها کند و لمس از آستانه جابجایی تجاوز نکند.
// UITapGestureRecognizer با پشتیبانی از Double Tap
class InteractiveImageViewController: UIViewController {
private var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Single Tap — نمایش/مخفی کردن عناصر کنترلی
let singleTap = UITapGestureRecognizer(
target: self,
action: #selector(handleSingleTap)
)
imageView.addGestureRecognizer(singleTap)
// Double Tap — بزرگنمایی تصویر
let doubleTap = UITapGestureRecognizer(
target: self,
action: #selector(handleDoubleTap)
)
doubleTap.numberOfTapsRequired = 2
// Single Tap فقط زمانی فعال میشود که Double Tap تشخیص داده نشود
singleTap.require(doubleTap.toFail())
imageView.addGestureRecognizer(doubleTap)
}
@objc private func handleSingleTap() { /* نمایش کنترلهای پخش */ }
@objc private func handleDoubleTap() { /* زوم کردن */ }
}الگوی مهم: هنگام پشتیبانی همزمان از Single و Double Tap باید require(_:toFail:) فراخوانی شود. بدون این، single tap بلافاصله فعال میشود و به سیستم اجازه نمیدهد منتظر ضربه دوم بماند. iOS همچنین تشخیص Tap را از طریق UIControl.addTarget پشتیبانی میکند — برای UIButton، UISwitch و سایر عناصر کنترلی. کنترلهای داخلی UIKit قبلاً پردازش استاندارد Tap را دارند و افزودن UITapGestureRecognizer روی آنها میتواند منجر به تعارض شود.
View.setOnClickListener — روش استاندارد Android SDK برای پردازش کلیکها روی View. هنگامی که کاربر View را لمس میکند و انگشت را روی همان عنصر رها میکند (touch down → touch up در محدوده View)، متد onClick() فراخوانی میشود. Android به طور خودکار افکت ripple (در API 21+) با انیمیشن لمس اضافه میکند. دکمه در حالت PRESSED فشرده در نظر گرفته میشود که به صورت بصری از طریق انتخابگر یا RippleDrawable نمایش داده میشود.
// setOnClickListener در Fragment با Data Binding
class ItemListFragment : Fragment() {
private var binding: FragmentItemListBinding? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentItemListBinding.bind(view)
binding.submitButton.setOnClickListener {
submitForm()
}
// شنونده با debounce برای جلوگیری از کلیک دوگانه
binding.submitButton.setOnClickListener(
DebouncingClickListener {
submitForm()
}
)
}
private fun submitForm() {
// ارسال دادههای فرم
}
}Debounce — الگوی مهم در برنامهنویسی Android. کاربر ممکن است به طور تصادفی دکمه را دو بار در یک بازه زمانی کوتاه فشار دهد که منجر به ارسال دوبرابری فرم یا اجرای دوبرابری عمل میشود. راهحل: پوشش DebouncingClickListener که کلیکهای تکراری را در عرض 500–1000 میلیثانیه مسدود میکند. Google استفاده از این رویکرد را در مثالهای رسمی Android Architecture Components توصیه میکند. برای RecyclerView، setOnItemClickListener از طریق ListAdapter با رابط callback فراهم شده است.
Double Tap (ضربه دوگانه) — دو Tap متوالی با فاصله حداکثر 300–400 میلیثانیه. برای بزرگنمایی تصاویر (نقشهها، عکسها)، لایکها در شبکههای اجتماعی (Instagram، Twitter)، بازگشت به ابتدای لیست (Phone، Messages) استفاده میشود. Triple Tap (ضربه سهگانه) کمتر رایج است — عمدتاً برای قابلیتهای دسترسی (حالت تمام صفحه، VoiceOver) و در بازیها استفاده میشود.
پیادهسازی Double Tap نیاز به همگامسازی با Single Tap دارد: اگر هر دو ژست را به یک عنصر اضافه کنید، Single Tap با تأخیر کار میکند (سیستم منتظر ضربه دوم میماند). در iOS این تأخیر از طریق require(toFail:) کنترل میشود — Single Tap تا زمانی که سیستم مطمئن شود Double Tap رخ نمیدهد به تعویق میافتد. در Android از GestureDetector.OnDoubleTapListener با callbackهای onSingleTapConfirmed و onDoubleTap استفاده میشود. onSingleTapConfirmed فقط پس از زمان انتظار، زمانی که سیستم مطمئن است این یک ضربه تکی است، فراخوانی میشود.
// Double Tap در Android از طریق GestureDetector
class PhotoViewerActivity : AppCompatActivity() {
private var gestureDetector: GestureDetector? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
gestureDetector = GestureDetector(this, object : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapConfirmed(e: MotionEvent): Boolean {
toggleControls() // نمایش/مخفی کردن کنترلها
return true
}
override fun onDoubleTap(e: MotionEvent): Boolean {
zoomToPoint(e.x, e.y) // بزرگنمایی در نقطه لمس
return true
}
})
}
}Instagram-like double tap — الگوی محبوب UX برای برنامههای اجتماعی. ضربه دوگانه روی عکس انیمیشن لایک (آیکون قلب) را فعال میکند. از طریق GestureDetector در Android یا UITapGestureRecognizer با numberOfTapsRequired=2 در iOS پیادهسازی میشود. برای انیمیشن از Core Animation در iOS و ObjectAnimator/AnimatorSet در Android استفاده میشود. زمان پاسخ double tap باید حداقل باشد — کاربر پس از ضربه دوم انتظار انیمیشن فوری دارد.
Human Interface Guidelines اپل و Material Design گوگل الزامات مشخصی برای Tap دارند. حداقل اندازه touch-target: 44×44 pt برای iOS و 48×48 dp برای Android. این معادل ~9 میلیمتر روی صفحه است — اندازه نوک انگشت یک فرد بالغ متوسط. فاصله بین اهداف لمسی باید حداقل 8 pt/dp باشد تا از ضربههای نادرست جلوگیری شود.
| قانون | مقدار | دلیل |
|---|---|---|
| حداقل اندازه هدف | 44×44 pt (iOS) / 48×48 dp (Android) | اندازه متوسط نوک انگشت ~9 میلیمتر |
| فاصله بین اهداف | ≥8 pt / ≥8 dp | جلوگیری از ضربههای نادرست |
| بازخورد بصری | Highlight / Ripple | تأیید ثبت لمس |
| مدت انیمیشن ضربه | 100–200 میلیثانیه | کافی برای درک، کاهش سرعت رابط ندارد |
| پردازش Double Tap | نیاز به تأخیر Single Tap | جلوگیری از فعال شدن نادرست |
| نواحی لبه صفحه | منطقه برخورد افزایشیافته | جبران نحوه نگهداشتن دستگاه |
بازخورد بصری برای Tap اجباری است. کاربر باید ببیند که لمس ثبت شده است: تغییر رنگ، opacity، انیمیشن ripple یا highlight. بدون بازخورد، کاربر ممکن است دوباره فشار دهد و باعث اقدامات ناخواسته شود. در iOS، انیمیشن استاندارد touch highlight — تغییر شفافیت به 0.3 با مدت 0.15 ثانیه. در Android — افکت Material ripple که از نقطه لمس منتشر میشود. قبل از بازخورد بصری از تأخیر استفاده نکنید — کاربر باید همزمان با لمس واکنش را ببیند.
سوالات متداول
Tap — رویداد لمسی، Click — رویداد ماوس. در مرورگر، Tap با تأخیر 300 میلیثانیه به Click تبدیل میشود (برای تمایز از Double Tap Zoom). مرورگرهای مدرن (Chrome 32+، Safari 9.1+) این تأخیر را با meta viewport دارای width=device-width غیرفعال میکنند. برای پردازش یکپارچه از Pointer Events API استفاده کنید: pointerdown/pointerup برای همه دستگاههای ورودی (ماوس، لمس، قلم) مناسب هستند.
حداقل touch target — 44×44 نقطه (iOS) یا 48×48 dp (Android). این معادل تقریباً 9×9 میلیمتر روی صفحه فیزیکی است. اگر دکمه از نظر بصری کوچکتر است (مثلاً آیکون 24×24)، ناحیه ضربه را از طریق UIEdgeInsets (iOS) یا TouchDelegate (Android) افزایش دهید. فاصله بین اهداف مجاور باید حداقل 8 واحد باشد تا از ضربههای نادرست جلوگیری شود.
Double-click prevention از طریق مکانیزم debounce پیادهسازی میشود: پس از اولین کلیک، دکمه به مدت 500–1000 میلیثانیه مسدود میشود. در Android از DebouncingClickListener (راهحل آماده از Architecture Components) استفاده کنید. در iOS — ویژگی isEnabled دکمه را بلافاصله پس از فشار غیرفعال کرده و از طریق DispatchQueue.main.asyncAfter فعال کنید. در برنامههای وب — پس از اولین کلیک، پرچم disabled را روی عنصر button قرار دهید.
Long Tap (Long Press) — نگه داشتن انگشت روی صفحه به مدت 500+ میلیثانیه بدون حرکت. Tap — ضربه سریع (100–300 میلیثانیه). Tap عمل اصلی (Primary Action) را انجام میدهد، Long Tap — عمل ثانویه (منوی زمینه، ویرایش). در iOS Tap توسط UITapGestureRecognizer و Long Press توسط UILongPressGestureRecognizer پردازش میشود. در Android — setOnClickListener در مقابل setOnLongClickListener.
بله، قلمها به عنوان Tap پردازش میشوند از طریق API لمسی استاندارد. Apple Pencil force (نیروی فشار)، altitudeAngle (زاویه شیب) و azimuth (آزیموت) را منتقل میکند. S Pen در Android پارامترهای مشابهی را از طریق MotionEvent.getPressure() و getAxisValue(MotionEvent.AXIS_TILT) منتقل میکند. برای قلمها میتوان touch target را به 24×24 نقطه کاهش داد، زیرا دقت قلم از انگشت بیشتر است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید