Ellipsize هي آلية لقص النص، حيث بدلاً من قطع السطر على مستوى البكسل، تتم إضافة علامة حذف (…) في النهاية أو المنتصف، لإشارة المستخدم إلى أن النص لا يتسع في الحاوية. تُستخدم هذه التقنية في العناوين والأزرار وقوائم جهات الاتصال وأي مكونات واجهة مستخدم بعرض محدود. وفقًا لإرشادات تصميم مواد Google، فإن ellipsize هو السلوك القياسي لـ TextView و UILabel، ويدعم أربعة أوضاع للقص: البداية والوسط والنهاية والشريط المتحرك.
النقاط الرئيسية
Ellipsize (من ellipsis — علامة حذف) هي تقنية لعرض النص الذي يتجاوز حجم الحاوية. بدلاً من مجرد قص السطر عند الحد، يضيف ellipsize حرف علامة حذف (ثلاث نقاط، Unicode U+2026)، للإشارة إلى المستخدم بوجود محتوى مخفي.
المصطلح ثابت في Android SDK، حيث تحدد الخاصية android:ellipsize سلوك TextView عند التجاوز. في iOS، تسمى الوظيفة المماثلة بالقص وتدار عبر NSLineBreakMode. في الويب، تُستخدم خاصية CSS text-overflow بالقيمة ellipsis.
الغرض الرئيسي من ellipsize هو إعلام المستخدم بأن النص تم تقصيره. على عكس القص القائم على البكسل حيث يمكن كسر الكلمة إلى نصفين، يضمن ellipsize سهولة القراءة: توضع علامة الحذف بعد كلمة أو حرف كامل دون كسره. يتوافق هذا مع مبادئ Material Design وإرشادات Human Interface Guidelines.
استخدم ellipsize كلما كان عرض الحاوية ثابتًا وطول النص ديناميكيًا: عناوين المقالات، خلايا الجدول، الأزرار ذات التسميات، جهات الاتصال في القائمة، فتات الخبز ومسارات الملفات.
في Android، يتم تكوين ellipsize عبر السمة android:ellipsize في XML أو طريقة setEllipsize() في الكود. هناك أربعة أوضاع متاحة، كل منها يحدد أي جانب من النص سيتم قصه.
وضع END (الافتراضي في معظم الحالات) يقص نهاية السطر ويضع علامة الحذف على الجانب الأيمن من الحاوية. وضع START يقص البداية — علامة الحذف على اليسار، النص المرئي على اليمين. MIDDLE يقص المنتصف، مع إبقاء بداية ونهاية السطر مرئية. وضع MARQUEE هو تمرير متحرك للنص، حيث لا تظهر علامة الحذف ويتحرك النص بشكل دوري.
<!-- XML layout -->
<TextView
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Very long text that will be truncated"
android:ellipsize="end"
android:maxLines="1"
android:singleLine="true" />
<!-- Kotlin code -->
textView.setEllipsize(TextUtils.TruncateAt.MIDDLE)
مهم: ellipsize يعمل فقط مع maxLines أو singleLine. إذا لم يتم تحديد عدد الأسطر، سينمو TextView في الارتفاع ولن يتم تنشيط ellipsize. منذ Android 8.0 (API 26)، يدعم ellipsize وضع متعدد الأسطر مع maxLines > 1 — توضع علامة الحذف في نهاية السطر الأخير.
للاستخدام البرمجي، استدع TextUtils.TruncateAt مع إحدى القيم: END, START, MIDDLE, MARQUEE. القيمة NONE تعطل ellipsize.
من الناحية العملية، END مناسب لـ 90% من الحالات — يتوقع المستخدمون أن يتم قص النص في النهاية. يُستخدم MIDDLE لمسارات الملفات (مثال: "/User/.../project/main.kt") ليكون نهاية المسار مرئيًا. يُستخدم START للأسماء ذات البادئة المشتركة (مثال: "...@gmail.com").
في iOS، ما يعادل ellipsize هو خاصية lineBreakMode لفئة UILabel (و NSTextContainer لـ UITextView). ثلاثة أوضاع قص متاحة: .byTruncatingTail (نهاية)، .byTruncatingMiddle (وسط) و .byTruncatingHead (بداية).
وضع .byTruncatingTail يقابل android:ellipsize="end". .byTruncatingHead يقابل START، .byTruncatingMiddle يقابل MIDDLE. وضع .byClipping يقص النص بدون علامة حذف، وهو نادر الاستخدام في الواجهات الحديثة. وضع .byCharWrapping يلتف حسب الأحرف بدون قص.
let label = UILabel()
label.text = "نص طويل لا يتسع لحدود التسمية"
label.lineBreakMode = .byTruncatingMiddle
label.numberOfLines = 1
// يدعم NSAttributedString أيضًا lineBreakMode
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineBreakMode = .byTruncatingTail
في iOS، يعمل القص جنبًا إلى جنب مع numberOfLines. إذا كان numberOfLines = 1، يتم قص النص في سطر واحد. إذا كان numberOfLines = 2 — في السطر الثاني. يستخدم UITextView NSTextContainer.lineBreakMode، الذي يدعم أيضًا أوضاع القص الثلاثة.
خصوصية iOS: وضع .byTruncatingMiddle على UILabel قد يتصرف بشكل غير متوقع مع السلاسل القصيرة — إذا كانت السلسلة تتسع بالكامل، لا تظهر علامة الحذف. لضمان ظهور علامة الحذف على السلاسل القصيرة، استخدم منطقًا مخصصًا عبر sizeThatFits.
في تطوير الويب، يتم تنفيذ ellipsize عبر خاصية CSS text-overflow: ellipsis مع overflow: hidden و white-space: nowrap. هذه هي الطريقة القياسية لقص سطر بعلامة حذف في واجهات الويب.
.text-cell {
width: 250px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
خاصية text-overflow لا تعمل بدون overflow: hidden — يحتاج المتصفح إلى معرفة أن المحتوى يتم قصه. white-space: nowrap يمنع التفاف النص، وإلا سينتقل النص إلى السطر التالي ولن يحدث تجاوز.
للقص متعدد الأسطر (مثال: سطرين مع علامة حذف في نهاية الثاني)، كانت تُستخدم سابقًا الخاصية التجريبية -webkit-line-clamp، والتي تم توحيدها الآن كـ line-clamp في CSS Overflow Level 4.
عمليًا، text-overflow: ellipsis مدعوم من جميع المتصفحات الحديثة لأكثر من 10 سنوات وهو الطريقة الأكثر موثوقية لقص النص على الويب.
اختيار وضع ellipsize يؤثر على تجربة المستخدم ويمكن أن يحسن إدراك الواجهة أو يربك المستخدم. القاعدة الرئيسية: يتوقع المستخدم أن يكون الجزء المقتص حيث يكون أقل حاجة للفهم.
وضع END مناسب للعناوين والتسميات — يرى المستخدم بداية السطر ويفهم السياق. علامة حذف على اليمين تعني "هناك المزيد، لكنه لم يتسع". هذا هو الوضع الأكثر بديهية وانتشارًا.
وضع MIDDLE لا غنى عنه لمسارات الملفات وعناوين البريد الإلكتروني والمعرفات الطويلة. عندما يحتوي نهاية السطر على معلومات فريدة (اسم ملف، نطاق)، يجب أن يرى المستخدم ذلك تحديدًا، بينما يمكن تقصير البداية. مثال: "/User/.../important_document.pdf" — اسم الملف مرئي فورًا.
وضع START نادر الاستخدام ولكنه مفيد لقائمة جهات اتصال ذات بادئة مشتركة — على سبيل المثال، "...@gmail.com" بدلاً من "username@gmail.com" عندما تنتمي جميع العناوين إلى نفس النطاق. ومع ذلك، غالبًا ما يربك هذا النمط أكثر مما يساعد. وفقًا لمجموعة Nielsen Norman Group، يقرأ المستخدمون من اليسار إلى اليمين ويتوقعون معلومات مهمة في البداية، لذا فإن قص START يزيد العبء المعرفي.
وضع MARQUEE (نص متحرك) مناسب فقط للعناصر أحادية السطر ذات تردد تحديث منخفض: المسار الحالي في مشغل، شريط أخبار، شريط حالة. لا تستخدم marquee للجداول أو القوائم أو النماذج — فالحركة تشتت الانتباه وتقلل الأداء على الأجهزة الضعيفة.
المشكلة الأولى — ellipsize لا يعمل. السبب الأكثر شيوعًا هو عدم وجود حد لعدد الأسطر. بدون maxLines، ينمو TextView في الارتفاع ولا يحدث تجاوز في العرض. الحل: حدد دائمًا maxLines (أو singleLine="true" لسطر واحد).
المشكلة الثانية — علامة الحذف لا تظهر عند تغيير النص برمجيًا. بعد استدعاء setText()، قد لا يعيد TextView الرسم بشكل صحيح. الحل: استدع invalidate() أو post(() -> requestLayout()) بعد تغيير النص.
المشكلة الثالثة — سلوك مختلف على إصدارات Android المختلفة. قبل API 23، لم يكن ellipsize في وضع متعدد الأسطر (maxLines > 1) مدعومًا. الحل: للتوافق، تحقق من Build.VERSION.SDK_INT واستخدم ViewCompat.setEllipsize() من AndroidX.
المشكلة الرابعة — حرف علامة الحذف لا يظهر في الخطوط المخصصة. إذا كان الخط لا يحتوي على الرمز U+2026، يتم استبدال علامة الحذف بثلاث نقاط. الحل: تحقق من وجود رمز ellipsis في الخط أو أضف خطًا احتياطيًا عبر fontFamily.
الأسئلة الشائعة
نعم، maxLines أو singleLine إلزامي. بدون تحديد عدد الأسطر، سيتوسع TextView في الارتفاع ولن يتم تنشيط القص.
Ellipsize يضيف علامة حذف عند نقطة القطع، لإعلام المستخدم بالنص المخفي. Clip ببساطة يقطع النص عند الحدود دون أي مؤشر.
text-overflow: ellipsis القياسي يقطع بعد كلمة كاملة. للقص في منتصف الكلمة، استخدم overflow-wrap: break-word أو حل JavaScript مع قياس العرض.
نعم، عبر خاصية textContainer.lineBreakMode لـ NSTextContainer. افتراضيًا، يستخدم UITextView .byWordWrapping؛ قم بتغييره إلى .byTruncatingTail/Middle/Head للقص.
استدع textView.setEllipsize(null) أو textView.setEllipsize(TextUtils.TruncateAt.NONE). بعد ذلك، سيلتف النص بدلاً من قصه.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا