الورقة (Sheet) في التطوير المحمول — ما هي، أنواعها وكيف تعمل

المؤلف: IT Sectr نُشر: 2026-06-10 وقت القراءة: 10 دق

الورقة (Sheet) هي مكون واجهة مستخدم يظهر في الجزء السفلي من الشاشة فوق المحتوى الرئيسي ويوفر إجراءات أو معلومات إضافية. Bottom Sheet هو النوع الأكثر شيوعاً، المُعرّف في إرشادات Material Design 3 (Google, 2024). على عكس نوافذ الحوار، لا يحجب Sheet التفاعل مع الخلفية بالكامل ويدعم حالتي collapsed و expanded. فهم أنواع وسلوك Sheet ضروري لبناء تنقل مريح في التطبيقات المحمولة.

النقاط الرئيسية

  • الورقة (Sheet) هي مكون واجهة يظهر من أسفل الشاشة فوق المحتوى الرئيسي
  • Bottom Sheet يمكن أن يكون قياسياً (غير مشروط) ومشروطاً — للإجراءات الإجبارية
  • Material Design 3 يحدد حالتين: collapsed و expanded مع السحب
  • على iOS يتم تنفيذ Sheet عبر UISheetPresentationController في UIKit و .sheet في SwiftUI
  • في Flutter يتم إنشاء Bottom Sheet عبر showBottomSheet و showModalBottomSheet

ما هي الورقة (Sheet) في التطبيقات المحمولة

الورقة (Sheet) هي مكون واجهة سطحي ينزلق من أسفل الشاشة ويعرض محتوى أو إجراءات إضافية دون إبعاد المستخدم عن الشاشة الحالية. على عكس الانتقالات إلى ملء الشاشة، تحافظ Sheet على السياق: يرى المستخدم شاشة الخلفية ويفهم من أين ظهرت Sheet.

تعتمد بنية Sheet على حاوية بارتفاع قابل للتعديل. في حالتها الدنيا (collapsed)، يكون جزء فقط من المحتوى مرئياً — عادةً عنوان أو لوحة صغيرة. يمكن للمستخدم سحب Sheet للأعلى لتوسيعها (expanded) أو التمرير لأسفل لإغلاقها. يشبه هذا السلوك ورقة مادية تُسحب من تحت كومة — ومن هنا جاء الاسم.

تسلط Google في إرشادات Material Design 3 (2024) الضوء على سيناريوهين رئيسيين لاستخدام Sheet: عرض إجراءات إضافية لم تكن موجودة في شريط الأدوات الرئيسي، وعرض نماذج أو معلومات مفصلة دون الانتقال إلى شاشة منفصلة. على iOS، أضافت Apple دعماً نظامياً لـ Sheet بدءاً من iOS 15 عبر UISheetPresentationController، مما يؤكد عالمية هذا النمط.

أنواع Bottom Sheet: قياسي ومشروط وموسع

Material Design يحدد ثلاثة أنواع من Bottom Sheet، لكل منها سلوكه ومجال استخدامه. يؤثر اختيار النوع الصحيح مباشرة على تجربة المستخدم والامتثال لإرشادات المنصة.

Bottom Sheet قياسي

Bottom Sheet القياسي هو مكون غير مشروط: يمكن للمستخدم التفاعل مع شاشة الخلفية دون إغلاق Sheet. على سبيل المثال، أثناء تصفح قائمة منتجات في الخلفية، يرى المستخدم عوامل تصفية في Bottom Sheet ويمكنه تغييرها دون إغلاق اللوحة. تضبط Sheet ارتفاعها وفقاً للمحتوى — من 30% إلى 90% من الشاشة.

Bottom Sheet القياسي لا يحجب الخلفية ويسمح بالتفاعل مع المحتوى الرئيسي. هذا هو الفرق الرئيسي عن Sheet المشروطة، التي تتطلب إجراءً إجبارياً للمتابعة. استخدم Sheet قياسية عندما لا تكون المعلومات الإضافية حاسمة للسيناريو الرئيسي.

Bottom Sheet مشروطة

Bottom Sheet المشروطة تحجب التفاعل مع شاشة الخلفية حتى يقوم المستخدم بإجراء داخل Sheet. تظهر هذه Sheet دائماً في حالة expanded وتتطلب إغلاقاً صريحاً — عبر زر أو إجراء أو تمرير لأسفل. يوصي Material Design بـ Sheet المشروطة لنماذج تسجيل الدخول والتأكيدات والإعدادات الحرجة.

على Android، يتم تنفيذ Bottom Sheet المشروطة عبر BottomSheetDialogFragment، الذي يحجب الخلفية تلقائياً. على iOS، يوفر السلوك المماثل الإصدار المشروط من UISheetPresentationController مع المعامل .mediumDetent. يجب استخدام Sheet المشروطة فقط عندما يتطلب السياق انتباه المستخدم.

Bottom Sheet موسعة

Bottom Sheet الموسعة تجمع بين خصائص القياسية والمشروطة: تبدأ كغير مشروطة في حالة collapsed، ولكن عند السحب لأعلى تصبح مشروطة. عملياً، هذا يعني أن المستخدم يمكنه أولاً إلقاء نظرة خاطفة على المحتوى ثم اتخاذ القرار — توسيع Sheet للدراسة التفصيلية أو إغلاقها.

هذا النمط شائع بشكل خاص في الخرائط والملاحين، حيث تظهر اللوحة السفلية معلومات موجزة عن نقطة مسار، وعند التمرير لأعلى تتوسع مع التفاصيل. تستخدم Google Maps هذا النوع الموسع بالضبط لعرض المعلومات عن الأماكن والمسارات.

نوع Sheetحجب الخلفيةالحالة الأوليةمثال
قياسيلاCollapsedعوامل تصفية في الكتالوج
مشروطنعمExpandedنموذج تسجيل دخول
موسعجزئيCollapsedبطاقة مكان

Bottom Sheet على Android: Material Design و Jetpack Compose

Android SDK يوفر عدة واجهات برمجية لتنفيذ Bottom Sheet، بدءاً من النهج الكلاسيكي القائم على View وصولاً إلى Jetpack Compose الحديث. تتضمن مكتبة Material Components لنظام Android تطبيقات جاهزة لـ BottomSheetDialogFragment و BottomSheetBehavior.

BottomSheetBehavior في تخطيط XML

BottomSheetBehavior هو فئة من Material Components تُرفق بأي View وتتحكم في موضعها على الشاشة. يحدد المطور ثلاث حالات: STATE_COLLAPSED و STATE_EXPANDED و STATE_HIDDEN. يتعامل Behavior تلقائياً مع إيماءات السحب والرسوم المتحركة.

kotlin
val sheet = findViewById<View>(R.id.bottom_sheet)
val behavior = BottomSheetBehavior.from(sheet)
behavior.state = BottomSheetBehavior.STATE_COLLAPSED
behavior.peekHeight = 200

Bottom Sheet في Jetpack Compose

Jetpack Compose يوفر واجهة برمجية تصريحية أكثر عبر مكون ModalBottomSheet من Material 3. على عكس النهج القائم على View، في Compose تكون Bottom Sheet دالة composable تقبل الحالة والمحتوى. تقوم Sheet تلقائياً بتحريك الظهور والإخفاء وتغييرات الارتفاع عند السحب.

kotlin
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun FilterSheet(onDismiss: () -> Unit) {
    ModalBottomSheet(onDismissRequest = onDismiss) {
        Text("تصفيات")
        Button(onClick = onDismiss) { Text("تطبيق") }
    }
}

BottomSheetDialogFragment للسيناريوهات المشروطة

BottomSheetDialogFragment هو DialogFragment متخصص يُعرض كـ Bottom Sheet. يتعامل تلقائياً مع الشرطية ودورة الحياة وتغييرات التكوين. يحتاج المطور فقط إلى تجاوز onCreateView وإرجاع تخطيط Sheet. وفقاً لوثائق Google (Android Developers, 2024)، يعتبر BottomSheetDialogFragment الطريقة الموصى بها لـ Bottom Sheets المشروطة في Android الكلاسيكي.

Sheet على iOS: UISheetPresentationController و SwiftUI

Apple أدخلت دعماً نظامياً لـ Sheet بدءاً من iOS 15 عبر UISheetPresentationController. قبل ذلك، كان المطورون ينفذون Bottom Sheet يدوياً عبر انتقالات مخصصة أو مكتبات طرف ثالث. يدعم Sheet الأصلي من Apple نقاط التوقف (detents) — مستويات توسع محددة مسبقاً.

UISheetPresentationController في UIKit

UISheetPresentationController هو وحدة تحكم عرض مدمجة تعرض View Controller كـ Sheet. يحدد المطور مصفوفة من نقاط التوقف — قيم الارتفاع التي يمكن أن يتوقف عندها Sheet. أضاف iOS 16 نقاط توقف مخصصة بارتفاع عشوائي. توصي Apple باستخدام نقطتي التوقف medium (.medium) و large (.large) كأساسيتين.

swift
let viewController = MySheetViewController()
if let sheet = viewController.sheetPresentationController {
    sheet.detents = [.medium, .large]
    sheet.prefersGrabberVisible = true
    sheet.preferredCornerRadius = 16
}
present(viewController, animated: true)

معدل .sheet في SwiftUI

SwiftUI يوفر المعدل .sheet، الذي يربط عرض Sheet بحالة. عندما يصبح متغير published بقيمة true، يعرض SwiftUI Sheet تلقائياً. يدعم SwiftUI أيضاً نقاط التوقف عبر المعدل .presentationDetents، المضاف في iOS 16.

swift
struct ContentView: View {
    @State private var showSheet = false

    var body: some View {
        Button("إظهار الورقة") { showSheet = true }
            .sheet(isPresented: $showSheet) {
                FilterView()
                    .presentationDetents([.medium, .large])
            }
    }
}

Sheet في الأطر متعددة المنصات: Flutter و React Native

الأطر متعددة المنصات تدعم أيضاً Bottom Sheet، مكيّفة السلوك حسب المنصة المستهدفة. يوفر Flutter و React Native تطبيقات مدمجة ومخصصة بدرجات مختلفة من المرونة.

Bottom Sheet في Flutter

Flutter SDK يحتوي على طريقتين لعرض Bottom Sheet: showBottomSheet (قياسية) و showModalBottomSheet (مشروطة). يتبع Material Design في Flutter نفس المبادئ كما في Android — تظهر Sheet من الأسفل، وتدعم السحب، ولها ارتفاع قابل للتعديل. للسلوك الموسع مع نقاط التوقف، يُستخدم DraggableScrollableSheet.

dart
Scaffold.of(context).showBottomSheet((context) {
    return Container(
        padding: EdgeInsets.all(16),
        child: Column(
            children: [
                Text("محتوى الورقة"),
                ElevatedButton(
                    onPressed: () => Navigator.of(context).pop(),
                    child: Text("إغلاق")
                )
            ]
        )
    );
})

Bottom Sheet في React Native

React Native لا يحتوي على مكون Bottom Sheet مدمج في نواته، لذلك يستخدم المطورون مكتبات طرف ثالث. الأكثر شيوعاً هي @gorhom/bottom-sheet (أكثر من 7 آلاف نجمة على GitHub، 2024). توفر Bottom Sheet مدفوعة بالإيماءات مع دعم نقاط الالتقاط والرسوم المتحركة والرؤوس الثابتة. المكتبة مبنية على Reanimated 2 و Gesture Handler لأداء 60 إطاراً في الثانية.

أفضل الممارسات والأخطاء الشائعة

الاستخدام الصحيح لـ Bottom Sheet يتطلب الامتثال لإرشادات المنصة وفهم السيناريوهات التي تكون فيها Sheet مناسبة. دعنا نستعرض التوصيات الرئيسية والأخطاء الشائعة عند تصميم Sheets.

متى تستخدم Bottom Sheet

Bottom Sheet مثالية للإجراءات التكميلية للمحتوى الرئيسي على الشاشة. عوامل التصفية والفرز واختيار الخيارات والمعلومات الموجزة عن عنصر — سيناريوهات نموذجية. يوصي Material Design باستخدام Bottom Sheet للأدوات التي لا ينبغي أن تشغل الشاشة بأكملها ولكنها تتطلب مساحة أكبر من Action Sheet أو Popup Menu.

متى لا تستخدم Bottom Sheet

لا تستخدم Bottom Sheet للتحذيرات الحرجة أو الأخطاء — فنوافذ الحوار أكثر ملاءمة لهذا. تجنب Sheets التي تحتوي على عدد كبير من حقول الإدخال التي تتطلب التمرير: يجد المستخدم صعوبة في الوصول إلى لوحة المفاتيح ويفقد السياق. إذا كانت Sheet تحتوي على أكثر من سبعة عناصر إجراء، ففكر في شاشة منفصلة بدلاً من Sheet.

خطأ: وضع collapsed مرتفع جداً

خطأ شائع هو تعيين peekHeight (الارتفاع في الحالة المطوية) إلى أكثر من 40% من الشاشة. لا يفهم المستخدم ما إذا كان يرى Sheet بالكامل أم يمكن توسيعها. يوصي Material Design بـ peekHeight في حدود 15-30% من ارتفاع الشاشة لترك جزء ملحوظ من المحتوى مخفياً وتحفيز السحب.

خطأ: تجاهل إيماءة السحب على iOS

على iOS، يتوقع المستخدمون إمكانية إغلاق Sheet عن طريق التمرير لأسفل من أي موضع. إذا قمت بتعطيل هذه الإيماءة (عبر UISheetPresentationController.prefersEdgeAttachedInCompactHeight)، يشعر المستخدم بالإحباط عند محاولة إغلاق Sheet بالطريقة المعتادة. تؤكد إرشادات واجهة المستخدم من Apple (2024) أن التمرير للإغلاق هو توقع أساسي لمستخدمي iOS.

الأسئلة الشائعة

ما الفرق بين Bottom Sheet ونافذة الحوار؟

Bottom Sheet لا يحجب الخلفية بالكامل ويدعم السحب، بينما نافذة الحوار مشروطة وتتطلب إجراءً إجبارياً. Bottom Sheet مناسب أكثر للخيارات التكميلية، ونافذة الحوار للتأكيدات الحرجة.

هل يمكن استخدام Bottom Sheet مع لوحة المفاتيح؟

نعم، ولكن يتطلب ضبط adjustResize أو adjustPan في بيان Android. على iOS، ترفع لوحة المفاتيح Sheet تلقائياً. يتطلب Flutter و React Native معالجة يدوية عبر MediaQuery للوضع الصحيح.

كم عدد العناصر الأمثل لوضعها في Bottom Sheet؟

يُوصى بما لا يزيد عن 5-7 عناصر في Sheet قياسية. إذا كان هناك محتوى أكثر، استخدم التمرير أو التقسيم إلى فئات. ينصح Material Design بعدم تجاوز 90% من ارتفاع الشاشة في الحالة الموسعة.

كيفية التعامل مع إغلاق Sheet عند النقر على الخلفية؟

لـ Sheet مشروطة، قم بتعيين setCancelable(true) على Android أو isModalInPresentation = false على iOS. في Jetpack Compose، يتعامل onDismissRequest تلقائياً مع النقر على الخلفية. في SwiftUI، التمرير لأسفل هو السلوك الافتراضي.

هل يدعم Bottom Sheet إمكانية الوصول؟

نعم، جميع التطبيقات الأصلية تدعم VoiceOver و TalkBack. تأكد من أن FocusManager ينقل التركيز بشكل صحيح إلى Sheet عند فتحها ويعيده عند إغلاقها. تتطلب التطبيقات المخصصة تكويناً يدوياً لإمكانية الوصول.

الملخص

  • الورقة (Sheet) هي مكون واجهة ينزلق من أسفل الشاشة لمحتوى إضافي دون الانتقال إلى شاشة جديدة
  • ثلاثة أنواع من Sheet: قياسية (غير مشروطة)، مشروطة (مع حجب الخلفية)، وموسعة (مجمعة)
  • Material Design 3 يحدد Bottom Sheet بحالتي collapsed و expanded ودعم السحب
  • على Android يتم تنفيذها عبر BottomSheetBehavior و BottomSheetDialogFragment و ModalBottomSheet في Compose
  • على iOS يُستخدم UISheetPresentationController مع نقاط التوقف منذ iOS 15 والمعدل .sheet في SwiftUI
  • في الأطر متعددة المنصات Bottom Sheet متاح عبر showBottomSheet (Flutter) و @gorhom/bottom-sheet (React Native)
  • تجنب Sheets للتحذيرات الحرجة والنماذج ذات الحقول الكثيرة — استخدم شاشات منفصلة

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا