النقر هو الإيماءة الأساسية للواجهات اللمسية: لمسة واحدة للشاشة بالإصبع متبوعة بالرفع. النقر هو الإجراء الأساسي في أنظمة التشغيل المحمولة — فتح التطبيقات، الضغط على الأزرار، اختيار عناصر القائمة. يتم التعرف عليه خلال 100–300 مللي ثانية ويُولد حدث ضغط. في iOS تتم معالجته عبر UITapGestureRecognizer، وفي Android — عبر setOnClickListener أو View.onClick.
النقاط الرئيسية
النقر (اللمس، الضغط) هو إيماءة اللمس السريع للشاشة اللمسية بإصبع أو قلم. تتكون الإيماءة من مرحلتين: اللمس لأسفل والرفع، وتحدثان في نفس المكان دون حركة. يتعرف النظام على النقر عندما لا تتجاوز الفترة الزمنية بين الضغط والرفع قيمة حدية (عادة 300–500 مللي ثانية). إذا أبقى المستخدم إصبعه لفترة أطول — تتحول الإيماءة إلى ضغط مطول.
النقر هو أساس تجربة المستخدم المحمولة. على جميع المنصات المحمولة، يحل النقر محل الضغط الأيسر للفأرة المستخدم في واجهات سطح المكتب. على عكس ضغط الفأرة، لا يحتوي النقر على معدّلات (Shift+نقر، Ctrl+نقر) ولا تمرير مؤشر — هذا القيد يُشكل تصميم الواجهات المحمولة. للتعويض عن عدم وجود معاينة مسبقة، تستخدم المنصات المحمولة ردود فعل بصرية: إبراز عند اللمس، تأثير تموج في Android، تغيير الشفافية في iOS.
تشريح النقر يشمل خمس مراحل على مستوى النظام: تنشيط المستشعر (لمس)، تحديد الإحداثيات، تصفية الضوضاء (يجب ألا يتحرك الإصبع أكثر من مسافة حدية)، انتظار الاكتمال (رفع أو إبقاء)، التصنيف (نقر، ضغط مطول، سحب). تعالج وحدات التحكم اللمسية الحديثة هذه الدورة في 8–16 مللي ثانية بمعدل استقصاء 60–120 هرتز.
النقر والضغط حدثان مختلفان بفيزياء مختلفة. الضغط هو حدث فأرة يحدث عند ضغط زر الفأرة ورفعه في نفس الموضع. النقر هو حدث شاشة لمسية يحدث عند لمس الإصبع. على الأجهزة المحمولة، يحوّل المتصفح النقر إلى حدث ضغط مع تأخير 300–350 مللي ثانية (لمحاكاة تكبير النقر المزدوج). كان هذا التأخير تاريخياً مشكلة للويب المحمول حتى قدمت Apple وGoogle meta viewport مع user-scalable=no.
| المعلمة | النقر (لمسي) | الضغط (فأرة) |
|---|---|---|
| جهاز الإدخال | إصبع، قلم | مؤشر الفأرة |
| المراحل | touchstart → touchend | mousedown → mouseup |
| معاينة (تمرير) | غير متوفرة | متوفرة (hover) |
| التأخير | 0–500 مللي ثانية | 0 مللي ثانية |
| الدقة | منخفضة (الإصبع أعرض من المؤشر) | عالية (على مستوى البكسل) |
| المعدّلات | لا يوجد | Shift, Ctrl, Cmd |
| المتعدد | لمس متعدد (إصبعان+) | لا (مؤشر واحد) |
أحداث اللمس هي واجهة برمجة تطبيقات منفصلة عن أحداث الفأرة. أحداث اللمس (touchstart، touchmove، touchend) تنقل مصفوفة من نقاط اللمس (TouchList)، الإحداثيات، الضغط، وحجم منطقة اللمس (radiusX، radiusY). أحداث الفأرة تنقل فقط إحداثيات المؤشر. المتصفحات الحديثة تُركّب حدث ضغط من touchend إذا لم تكن هناك حركة إصبع ولم يكن هناك حدث touchcancel. Pointer Events API تجمع بين كلا النهجين، مما يوفر معالجة موحدة لجميع أجهزة الإدخال.
UITapGestureRecognizer هو المكتشف القياسي للنقر الفردي والمتعدد في iOS SDK. يدعم تكوين numberOfTapsRequired (عدد النقرات المتتالية) وnumberOfTouchesRequired (عدد الأصابع الملامسة في وقت واحد). ينتقل المكتشف إلى حالة UIGestureRecognizerStateRecognized عندما يرفع المستخدم إصبعه ولا يتجاوز اللمس حد الحركة.
// UITapGestureRecognizer مع دعم النقر المزدوج
class InteractiveImageViewController: UIViewController {
private var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// نقرة واحدة — إظهار/إخفاء عناصر التحكم
let singleTap = UITapGestureRecognizer(
target: self,
action: #selector(handleSingleTap)
)
imageView.addGestureRecognizer(singleTap)
// نقر مزدوج — تكبير الصورة
let doubleTap = UITapGestureRecognizer(
target: self,
action: #selector(handleDoubleTap)
)
doubleTap.numberOfTapsRequired = 2
// يتم تشغيل النقرة الواحدة فقط إذا لم يتم التعرف على النقر المزدوج
singleTap.require(doubleTap.toFail())
imageView.addGestureRecognizer(doubleTap)
}
@objc private func handleSingleTap() { /* إظهار عناصر التحكم */ }
@objc private func handleDoubleTap() { /* تكبير */ }
}نمط مهم: عند دعم النقر المفرد والمزدوج في وقت واحد، يجب استدعاء require(_:toFail:). بدون ذلك، سيتم تشغيل النقر المفرد فوراً، دون السماح للنظام بانتظار الضغطة الثانية. iOS يدعم أيضاً التعرف على النقر عبر UIControl.addTarget — لأزرار UIButton وUISwitch وعناصر التحكم الأخرى. عناصر التحكم المدمجة في UIKit لديها بالفعل معالجة قياسية للنقر، وإضافة UITapGestureRecognizer فوقها قد يؤدي إلى تعارضات.
View.setOnClickListener هو الأسلوب القياسي في Android SDK لمعالجة النقرات على View. عندما يلمس المستخدم View ويرفع إصبعه على نفس العنصر (لمس لأسفل → لمس لأعلى داخل View)، يتم استدعاء طريقة onClick(). يضيف Android تلقائياً تأثير تموج (على 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 مع واجهة رد اتصال.
النقر المزدوج — نقرتان متتاليتان بفاصل لا يزيد عن 300–400 مللي ثانية. يُستخدم لتكبير الصور (خرائط، صور)، الإعجابات في الشبكات الاجتماعية (Instagram، Twitter)، العودة إلى بداية القائمة (هاتف، رسائل). النقر الثلاثي أقل شيوعاً — يُستخدم أساساً لوظائف إمكانية الوصول (وضع ملء الشاشة، VoiceOver) وفي الألعاب.
تنفيذ النقر المزدوج يتطلب مزامنة مع النقر المفرد: إذا أضفت كلا الإيماءتين على عنصر واحد، سيتم تشغيل النقر المفرد مع تأخير (النظام ينتظر الضغطة الثانية). في iOS، تتم إدارة هذا التأخير عبر require(toFail:) — يتم تأجيل النقر المفرد حتى التأكد من عدم حدوث نقر مزدوج. في Android، يتم استخدام GestureDetector.OnDoubleTapListener مع استدعاءات onSingleTapConfirmed وonDoubleTap. يتم استدعاء onSingleTapConfirmed فقط بعد مهلة عندما يكون النظام متأكداً من أنها نقرة مفردة.
// النقر المزدوج في 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 هو نمط UX شائع للتطبيقات الاجتماعية. النقر المزدوج على صورة يُظهر رسوم متحركة للإعجاب (أيقونة قلب). يتم تنفيذه عبر GestureDetector في Android أو UITapGestureRecognizer مع numberOfTapsRequired=2 في iOS. للرسوم المتحركة، يُستخدم Core Animation في iOS وObjectAnimator/AnimatorSet في Android. يجب أن يكون زمن استجابة النقر المزدوج ضئيلاً — يتوقع المستخدم رسماً متحركاً فورياً بعد النقرة الثانية.
إرشادات واجهة المستخدم من Apple وMaterial Design من Google لديهما متطلبات محددة للنقر. الحجم الأدنى للهدف اللمسي: 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 | منع النقرات الخاطئة |
| رد الفعل البصري | إبراز / تموج | تأكيد تسجيل اللمس |
| مدة الرسوم المتحركة للنقر | 100–200 مللي ثانية | كافٍ للإدراك، لا يُبطئ الواجهة |
| معالجة النقر المزدوج | يتطلب تأخير النقر المفرد | منع التشغيل الخاطئ |
| مناطق حافة الشاشة | منطقة تأثير موسعة | تعويض عن قبضة الجهاز |
رد الفعل البصري إلزامي للنقر. يجب أن يرى المستخدم أن اللمس قد تم تسجيله: تغيير اللون، الشفافية، رسم متحرك تموجي أو إبراز. بدون رد فعل، قد يضغط المستخدم مرة أخرى، مما يسبب إجراءات غير مرغوب فيها. في iOS، الرسم المتحرك القياسي لإبراز اللمس هو تغيير الشفافية إلى 0.3 بمدة 0.15 ثانية. في Android — تأثير تموج Material ينتشر من نقطة اللمس. لا تؤخر رد الفعل البصري — يجب أن يرى المستخدم رد الفعل بالتزامن مع اللمس.
الأسئلة الشائعة
النقر هو حدث لمسي، الضغط هو حدث فأرة. في المتصفح، يتم تحويل النقر إلى ضغط مع تأخير 300 مللي ثانية (للتمييز عن تكبير النقر المزدوج). المتصفحات الحديثة (Chrome 32+، Safari 9.1+) تُعطل هذا التأخير مع meta viewport width=device-width. استخدم Pointer Events API للمعالجة الموحدة: pointerdown/pointerup مناسبة لجميع أجهزة الإدخال (فأرة، لمس، قلم).
الحد الأدنى للهدف اللمسي هو 44×44 نقطة (iOS) أو 48×48 dp (Android). هذا يتوافق تقريباً مع 9×9 مم على الشاشة الفعلية. إذا كان الزر أصغر بصرياً (مثلاً، أيقونة 24×24)، قم بزيادة منطقة التأثير عبر UIEdgeInsets (iOS) أو TouchDelegate (Android). يجب أن يكون التباعد بين الأهداف المتجاورة 8 وحدات على الأقل لتجنب النقرات الخاطئة.
منع النقر المزدوج يتم تنفيذه عبر آلية debounce: بعد النقرة الأولى، يتم حظر الزر لمدة 500–1000 مللي ثانية. في Android، استخدم DebouncingClickListener (حل جاهز من Architecture Components). في iOS، قم بتعطيل isEnabled للزر فوراً بعد الضغط وأعد تمكينه عبر DispatchQueue.main.asyncAfter. في تطبيقات الويب، ضع علامة disabled على عنصر الزر بعد النقرة الأولى.
الضغط المطول هو إبقاء الإصبع على الشاشة لمدة 500+ مللي ثانية دون حركة. النقر هو لمسة سريعة (100–300 مللي ثانية). النقر ينفذ الإجراء الرئيسي، الضغط المطول ينفذ إجراء ثانوياً (قائمة سياق، تحرير). في iOS، تتم معالجة النقر عبر UITapGestureRecognizer، والضغط المطول عبر UILongPressGestureRecognizer. في Android — setOnClickListener مقابل setOnLongClickListener.
نعم، تتم معالجة الأقلام كنقر عبر واجهة البرمجة اللمسية القياسية. Apple Pencil ينقل القوة (الضغط)، altitudeAngle، وazimuth. S Pen في Android ينقل معلمات مماثلة عبر MotionEvent.getPressure() وgetAxisValue(MotionEvent.AXIS_TILT). للأقلام، يمكنك تقليل الهدف اللمسي إلى 24×24 نقطة لأن دقة القلم أعلى من الإصبع.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.