{"id":"l-fig-2-4","courseId":"figma-ui-design","lang":"ar","kind":"lesson","summary":"اجمع بين الـ constraints للعناصر المثبّتة والـ Auto layout للمحتوى، لتتكيّف شاشة واحدة من Steady من الهاتف الصغير إلى الكبير، واختبرها بنسخ مغيّرة الحجم ومحتوى صعب يختبر حدود التخطيط.","html":"<p>سيعمل Steady على هواتف يتراوح عرضها بين نحو 360 و440 نقطة، والارتفاعات تتفاوت أكثر من ذلك. تصميم شاشة منفصلة لكل حجم فخّ في الصيانة: غيّر صف العادة في واحدة وعليك أن تتذكّر تغييره في أربع أخرى. الهدف شاشة واحدة تتكيّف، مبنية من القطع التي لديك أصلًا.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">نوعان من العناصر على الشاشة</h2>\n<p>انظر إلى شاشة Today وصنّف أجزاءها إلى نوعين.</p>\n<p><strong>عناصر مثبّتة على الشاشة</strong>: شريط التبويبات في الأسفل، وزر الإضافة العائم في الزاوية. يجب أن تبقى ملتصقة بحافّة مهما فعل المحتوى. هذه مهمّة <strong>الـ constraints</strong> (الدرس 1.4).</p>\n<p><strong>عناصر تتدفّق</strong>: الترويسة، وكتلة التقدّم، وقائمة العادات. تتراصّ واحدة بعد الأخرى، وتطول القائمة مع كل عادة. هذه مهمّة <strong>الـ Auto layout</strong> (الدرسان 2.1 و2.2).</p>\n<p>البنية الناتجة بسيطة وتعمل مع معظم شاشات التطبيقات:</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 680 300\" role=\"img\" aria-labelledby=\"l-fig-2-4-t1\"><defs><marker id=\"arrow-l-fig-2-4-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-fig-2-4-t1\">frame شاشة Today هو frame عادي. داخله frame اسمه Content يستخدم Auto layout عموديًا ويضمّ الترويسة والتقدّم وقائمة العادات؛ وهو مقيّد يسارًا ويمينًا وأعلى وأسفل. شريط التبويبات مقيّد يسارًا ويمينًا مع الأسفل، وزر الإضافة مقيّد يمينًا مع الأسفل.</title>\n  <rect class=\"d-box\" x=\"20\" y=\"20\" width=\"300\" height=\"260\" rx=\"16\"/>\n  <text class=\"d-label-strong\" x=\"36\" y=\"44\">Today (frame بلا Auto layout)</text>\n  <rect class=\"d-box-primary\" x=\"36\" y=\"56\" width=\"268\" height=\"150\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"48\" y=\"78\">Content: ‏Auto layout عمودي</text>\n  <rect class=\"d-box\" x=\"48\" y=\"88\" width=\"244\" height=\"24\" rx=\"4\"/>\n  <text class=\"d-label-muted\" x=\"56\" y=\"105\">Header</text>\n  <rect class=\"d-box\" x=\"48\" y=\"118\" width=\"244\" height=\"24\" rx=\"4\"/>\n  <text class=\"d-label-muted\" x=\"56\" y=\"135\">Progress</text>\n  <rect class=\"d-box\" x=\"48\" y=\"148\" width=\"244\" height=\"48\" rx=\"4\"/>\n  <text class=\"d-label-muted\" x=\"56\" y=\"176\">Habit list</text>\n  <circle class=\"d-dot\" cx=\"286\" cy=\"226\" r=\"12\"/>\n  <rect class=\"d-box-accent\" x=\"36\" y=\"244\" width=\"268\" height=\"28\" rx=\"6\"/>\n  <text class=\"d-label\" x=\"170\" y=\"263\" text-anchor=\"middle\">Tab bar</text>\n  <text class=\"d-label\" x=\"360\" y=\"90\">Content</text>\n  <text class=\"d-label-muted\" x=\"360\" y=\"110\">constraints: L+R, Top+Bottom</text>\n  <text class=\"d-label\" x=\"360\" y=\"160\">Add button</text>\n  <text class=\"d-label-muted\" x=\"360\" y=\"180\">constraints: Right, Bottom</text>\n  <text class=\"d-label\" x=\"360\" y=\"230\">Tab bar</text>\n  <text class=\"d-label-muted\" x=\"360\" y=\"250\">constraints: L+R, Bottom</text>\n  <path class=\"d-arrow\" d=\"M352 98 L308 120\" marker-end=\"url(#arrow-l-fig-2-4-1)\"/>\n  <path class=\"d-arrow\" d=\"M352 168 L300 222\" marker-end=\"url(#arrow-l-fig-2-4-1)\"/>\n  <path class=\"d-arrow\" d=\"M352 238 L306 254\" marker-end=\"url(#arrow-l-fig-2-4-1)\"/>\n</svg><figcaption>frame شاشة واحد، ونظاما تخطيط</figcaption></figure>\n<p>الـ frame الخاص بالشاشة نفسها بلا Auto layout. داخله يستخدم frame الـ <code dir=\"ltr\">Content</code> ‏Auto layout عموديًا، وله الـ constraints ‏<strong>Left and right, Top and bottom</strong>، فيملأ دائمًا المساحة بين شريط الحالة وشريط التبويبات. شريط التبويبات وزر الإضافة إخوة لـ <code dir=\"ltr\">Content</code> ولهما constraints على الحوافّ. وداخل <code dir=\"ltr\">Content</code>، كل شيء عرضه Fill container، فتتمدّد الصفوف مع الشاشة.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">خطأ شائع</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>وضع كل شيء في كومة Auto layout واحدة</span></p>\n<p>لفّ الشاشة كلها، بما فيها شريط التبويبات، في frame عمودي واحد بـ Auto layout يبدو مرتّبًا. لكن في الـ flow يجلس شريط التبويبات مباشرة بعد آخر عادة. ومع ثلاث عادات في هاتف طويل يطفو في منتصف الشاشة. العناصر المثبّتة مكانها خارج الـ flow، تتحكّم فيها الـ constraints.</p>\n</aside>\n<h2 id=\"sec-2\" tabindex=\"-1\">احترم مناطق النظام</h2>\n<p>الهواتف الحديثة تحجز مساحة في الأعلى لشريط الحالة وفتحة الكاميرا، وفي الأسفل لمؤشّر الشاشة الرئيسية (home indicator). المحتوى تحتها صعب القراءة أو مستحيل النقر. أضف padding في أعلى frame الـ <code dir=\"ltr\">Content</code> وفي أسفل شريط التبويبات حتى لا يقع هناك شيء مهم. الأحجام الدقيقة تختلف بين الأجهزة، فخذها من الـ UI kits الرسمية من Apple أو Google في Figma Community بدل التخمين.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">المحتوى ثنائي البعد: الـ Grid</h2>\n<p>تعرض شاشة Habit detail أربع بطاقات إحصاءات: الـ streak الحالي، وأفضل streak، ونسبة الإنجاز، وإجمالي مرّات التسجيل. على الهاتف تجلس في عمودين؛ وعلى الجهاز اللوحي، أربعًا في صف.</p>\n<p>وقت كتابة هذا الدرس، للـ Auto layout ‏flow من نوع <strong>Grid</strong> لهذا الغرض بالضبط. الـ frame الشبكي بـ Auto layout له عدد من الأعمدة والصفوف، وفجوات بينها، وأبناء يمكن أن يمتدّوا على أكثر من خلية. اضبط frame الإحصاءات على عمودين بفجوات 16 px (مطابقة للـ gutter في الـ Layout guide) في الهاتف؛ وفي نسخة الجهاز اللوحي، غيّره إلى 4 أعمدة. فتُرتَّب البطاقات الأربع نفسها من جديد دون إعادة رسمها.</p>\n<p>الـ Wrap (الدرس 2.2) سينقل البطاقات إلى أسطر جديدة أيضًا، لكن مع الـ Wrap تحتفظ كل بطاقة بعرضها، فتحصل على بقايا غير منتظمة. أما الـ Grid فيُبقي الأعمدة متساوية، وهذا ما تحتاجه لوحة إحصاءات.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">طقس تغيير الحجم</h2>\n<p>قبل أن تقبل صوفيا أي شاشة، تُجري الاختبار نفسه، ويجب أن تفعل مثلها:</p>\n<ol>\n<li>كرّر frame الشاشة مرّتين.</li>\n<li>غيّر عرض إحدى النسختين إلى 360 والأخرى إلى 440، واضبط الارتفاعات على هاتف قصير وآخر طويل.</li>\n<li>اقرأ كل نسخة من الأعلى إلى الأسفل. ابحث عن التداخلات، والقصّ غير المقصود، والعناصر الطافية في منتصف الشاشة، والفجوات التي كبرت بشكل غريب.</li>\n<li>أصلح الأصل، لا النسخ. واحذف النسخ حين ينجح الأصل.</li>\n</ol>\n<p>ثم اختبر المحتوى تحت الضغط، لأن المحتوى يكسر تخطيطات أكثر مما تكسرها العروض. استخدم اسم عادة من 40 حرفًا، وstreak من أربعة أرقام، وقائمة فارغة (“No habits yet”). وأخيرًا، كبّر كل text style بنحو 30% في نسخة. كثيرون يضبطون حجم نص أكبر في إعدادات هواتفهم، والصف الذي لا يعمل إلا عند 17 px سينكسر عندهم أولًا.</p>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">نصيحة</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>الـ breakpoints قرارات تخصّ المحتوى</span></p>\n<p>حين يتوقّف التخطيط عن العمل مع اتّساع الـ frame، فذلك العرض هو الـ breakpoint الخاص بك، لا رقم من قائمة أجهزة. إذا أصبحت أسطر قائمة العادات طويلة بشكل مزعج عند 600 px، فهناك يجب أن يبدأ تخطيط الجهاز اللوحي بلوحة جانبية.</p>\n</aside>\n<p>انتهى القسم 2: شاشاتك تتراصّ وتتمدّد وتلتفّ وتثبت بشكل صحيح. في القسم 3 تتوقّف عن إعادة بناء صف العادة في كل شاشة، وتحوّله إلى component.</p>\n","toc":[{"id":"sec-1","text":"نوعان من العناصر على الشاشة","level":2},{"id":"sec-2","text":"احترم مناطق النظام","level":2},{"id":"sec-3","text":"المحتوى ثنائي البعد: الـ Grid","level":2},{"id":"sec-4","text":"طقس تغيير الحجم","level":2}],"takeaways":["استخدم الـ constraints للعناصر المثبّتة على حوافّ الشاشة (شريط التبويبات، الزر العائم) والـ Auto layout للمحتوى الذي يتدفّق.","صمّم على عرض متوسط واحد، ثم أثبت أن الشاشة تعمل عند أصغر عرض وأكبر عرض تدعمهما.","أبعد المحتوى عن منطقتي شريط الحالة ومؤشّر الشاشة الرئيسية، وخذ أحجامهما الدقيقة من UI kit رسمي للمنصّة.","الـ Grid في الـ Auto layout يتعامل مع المحتوى ثنائي البعد مثل بطاقات الإحصاءات، ويمكن أن يتغيّر عدد الأعمدة بين الـ breakpoints.","اختبر تحت الضغط بنصوص طويلة وأحجام خط أكبر وحالات فارغة، لأن المحتوى الحقيقي يكسر التخطيطات أكثر مما يكسرها عرض الشاشة."],"further":[{"title":"Combine vertical, horizontal, and grid auto layout flows","url":"https://help.figma.com/hc/en-us/articles/31441443713047-Combine-vertical-horizontal-and-grid-auto-layout-flows"},{"title":"Use the grid auto layout flow","url":"https://help.figma.com/hc/en-us/articles/31289469907863-Use-the-grid-auto-layout-flow"},{"title":"Layout (Apple Human Interface Guidelines)","url":"https://developer.apple.com/design/human-interface-guidelines/layout"}],"quiz":[{"q":"<p>شاشة Today في Steady عبارة عن frame عمودي كبير واحد بـ Auto layout يضمّ الترويسة والقائمة وشريط التبويبات. في هاتف طويل ينتهي شريط التبويبات في منتصف الشاشة، تحت آخر عادة مباشرة. لماذا؟</p>","options":[{"text":"الـ Auto layout يضع شريط التبويبات مباشرة بعد إخوته، فيتبع المحتوى بدل الحافّة السفلية للشاشة.","why":"صحيح. في الـ flow يعتمد موضع شريط التبويبات على ما يسبقه. التثبيت على حافّة مهمّة الـ constraint."},{"text":"شريط التبويبات يحتاج الـ constraint ‏Scale.","why":"Scale سيغيّر حجم الشريط بشكل نسبي، ولن يثبّته في الأسفل مع ذلك."},{"text":"الهواتف الطويلة تحتاج ملف تصميم منفصلًا.","why":"شاشة واحدة يمكن أن تخدم ارتفاعات كثيرة. الملفات المنفصلة تضاعف عبء الصيانة."},{"text":"الـ Layout guide فيه صفوف قليلة.","why":"الـ Layout guides لا تحرّك الطبقات أبدًا. إنها أدوات بصرية مساعدة فقط."}],"answer":0},{"q":"<p>ما أكفأ طريقة للتحقّق من أن شاشة تعمل عبر أحجام الهواتف المختلفة؟</p>","options":[{"text":"إعادة رسم الشاشة من الصفر لكل عرض.","why":"إعادة الرسم لا تختبر شيئًا عن تكيّف تصميمك الواحد، وتخلق نسخًا تتباعد مع الوقت."},{"text":"تكبير لوحة العمل وتصغيرها.","why":"التكبير يغيّر طريقة عرضك، لا حجم الـ frame، فلا تُنفَّذ الـ constraints ولا قواعد تغيير الحجم أبدًا."},{"text":"الطلب من المطوّرين إخبارك إن انكسرت.","why":"اكتشاف أخطاء التخطيط بعد البناء يكلّف أكثر بكثير من تغيير حجم frame الآن."},{"text":"تكرار الـ frame وتغيير حجم النسخ إلى أضيق عرض وأعرض عرض تدعمهما.","why":"صحيح. تغيير الحجم يشغّل كل constraint وكل قاعدة Auto layout، فتظهر الأخطاء فورًا."}],"answer":3},{"q":"<p>في شاشة Habit detail، تجلس أربع بطاقات إحصاءات في عمودين على الهواتف. وعلى الأجهزة اللوحية تريدها أربعًا في صف واحد. أيّ أداة تناسب أكثر؟</p>","options":[{"text":"Auto layout أفقي مع Wrap وبطاقات بعرض ثابت.","why":"الـ Wrap قد يعمل، لكن البطاقات الثابتة العرض تترك فجوات غير منتظمة في معظم العروض. الـ Grid يُبقي الأعمدة متساوية."},{"text":"Auto layout من نوع Grid، بعمودين في frame الهاتف و4 في frame الجهاز اللوحي.","why":"صحيح. الـ Grid يضع العناصر في صفوف وأعمدة منتظمة، وتغيير عدد الأعمدة يعيد ترتيب البطاقات نفسها."},{"text":"أربعة frames منفصلة موضوعة يدويًا بالـ constraints.","why":"التموضع اليدوي يجب أن يُعاد لكل حجم ولكل بطاقة جديدة."},{"text":"Auto layout عمودي مع gap سالب.","why":"الـ gap السالب يجعل العناصر تتداخل؛ ولا يصنع أعمدة."}],"answer":1}],"exercise":{"kind":"order","items":["design-mid","content-frame","fill-children","constraints","resize-copies","stress","fix-original"],"title":"اجعل شاشة Today متجاوبة","prompt":"<p>لديك شاشة Today ثابتة وُضع كل شيء فيها يدويًا. رتّب هذه الخطوات بالترتيب الذي ستتّبعه لتجعلها تتكيّف من هاتف بعرض 360 px إلى آخر بعرض 440 px، بالطريقة التي تتّبعها صوفيا.</p>\n","hints":["لا يمكنك ضبط Fill container قبل أن يكون الأبناء داخل frame بـ Auto layout.","الاختبار يأتي بعد اكتمال البنية، والإصلاحات تذهب إلى الأصل لا إلى نسخ الاختبار.","صمّم، ثم لُفّ المحتوى، ثم اضبط الـ Fill، ثم ثبّت الحوافّ وتأكّد أن الصفوف تتمدّد، ثم اختبر العروض، ثم اختبر المحتوى تحت الضغط، ثم أصلح."],"explanation":"<p>ابدأ من <strong>تصميم واحد متقن بعرض متوسط</strong> حتى يكون لديك شيء يستحق التكييف. لُفّ الأجزاء المتدفّقة في <strong>frame محتوى عمودي بـ Auto layout</strong>، لأن Fill container لا يوجد إلا لأبناء الـ Auto layout. ثم اضبط عرض الصفوف والنصوص على <strong>Fill container</strong> لتتمدّد. بعد ذلك أضف <strong>الـ constraints</strong> في frame الشاشة لـ frame المحتوى وللعناصر المثبّتة؛ ولا يُظهر اختبار السحب السريع تمدّد الصفوف إلا لأن الـ Fill مضبوط عليها مسبقًا. الآن فقط <strong>تغيّر حجم النسخ</strong> إلى أضيق عرض وأعرضه، ثم <strong>تختبر المحتوى تحت الضغط</strong> بأسماء طويلة وقوائم فارغة ونص أكبر. وأخيرًا <strong>تصلح الأصل</strong> وتحذف النسخ، فيبقى هناك مصدر حقيقة واحد.</p>\n","checkLabels":{},"itemText":{"design-mid":"صمّم الشاشة بعرض متوسط مثل 393 px.","content-frame":"لُفّ الترويسة والتقدّم وقائمة العادات في frame عمودي بـ Auto layout اسمه Content.","fill-children":"اضبط عرض الصفوف والنصوص داخل Content على Fill container.","constraints":"اضبط الـ constraints (‏Content على Left and right وTop and bottom؛ وشريط التبويبات على Left and right وBottom؛ وزر الإضافة على Right وBottom)، ثم اسحب حافّة الشاشة لتوسيعها وتأكّد أن الصفوف تتمدّد معها.","resize-copies":"كرّر الشاشة وغيّر عرض النسخ إلى 360 و440 px.","stress":"اختبر النسخ تحت الضغط باسم عادة طويل، وقائمة فارغة، ونص أكبر بنحو 30%.","fix-original":"أصلح ما انكسر في الشاشة الأصلية، ثم احذف نسخ الاختبار."}},"words":631,"readMinutes":4}