تعلم كيفية التعامل بفعالية مع تغييرات اتجاه الشاشة في تطبيقاتك، مما يضمن تجربة مستخدم سلسة عبر الأجهزة والمنصات.
إتقان اتجاه الشاشة: دليل شامل للتعامل مع دوران الجهاز
في عالم اليوم متعدد الأجهزة، يعد التعامل مع اتجاه الشاشة بسلاسة أمرًا بالغ الأهمية لتوفير تجربة مستخدم إيجابية. سواء كان هاتفًا ذكيًا أو جهازًا لوحيًا أو حتى جهازًا قابلاً للطي، يتوقع المستخدمون أن تتكيف التطبيقات بسلاسة عند تدوير أجهزتهم. يقدم هذا الدليل نظرة شاملة على التعامل مع دوران الجهاز، ويغطي مختلف المنصات والتقنيات لضمان أن تكون تطبيقاتك متجاوبة وسهلة الاستخدام.
فهم اتجاه الشاشة
يشير اتجاه الشاشة إلى الاتجاه الذي يتم به عرض المحتوى على شاشة الجهاز. الاتجاهان الأساسيان هما:
- الوضع الرأسي (Portrait): تكون الشاشة أطول من عرضها. هذا هو الاتجاه المعتاد للهواتف الذكية.
- الوضع الأفقي (Landscape): تكون الشاشة أعرض من طولها. غالبًا ما يُفضل هذا الوضع لمشاهدة مقاطع الفيديو أو ممارسة الألعاب.
تدعم بعض الأجهزة والتطبيقات أيضًا:
- الوضع الرأسي المعكوس (Reverse Portrait): الوضع الرأسي مع تدوير الجهاز 180 درجة.
- الوضع الأفقي المعكوس (Reverse Landscape): الوضع الأفقي مع تدوير الجهاز 180 درجة.
لماذا يجب التعامل مع تغييرات اتجاه الشاشة؟
يمكن أن يؤدي الفشل في التعامل مع تغييرات اتجاه الشاشة إلى مجموعة متنوعة من المشكلات، بما في ذلك:
- مشكلات في التخطيط: قد تكون العناصر غير محاذاة أو مبتورة أو متداخلة مع بعضها البعض.
- فقدان البيانات: في بعض الحالات، قد يتم فقدان حالة النشاط أو التطبيق عند تدوير الشاشة.
- تجربة مستخدم سيئة: يمكن أن تؤدي التجربة المزعجة أو المعطلة إلى إحباط المستخدمين والإضرار بسمعة تطبيقك.
- مشكلات في الأداء: يمكن أن يؤثر إعادة العرض المتكرر وحسابات التخطيط على الأداء، خاصة على الأجهزة القديمة.
التعامل مع اتجاه الشاشة على منصات مختلفة
تختلف التقنيات المحددة للتعامل مع اتجاه الشاشة اعتمادًا على المنصة التي تطور لها. دعنا نفحص بعض المنصات الأكثر شيوعًا:
1. أندرويد (Android)
يوفر أندرويد عدة آليات للتعامل مع تغييرات اتجاه الشاشة. تشمل الأساليب الأكثر شيوعًا ما يلي:
أ. تغييرات التكوين (Configuration Changes)
بشكل افتراضي، يعيد أندرويد إنشاء النشاط (Activity) عند تغيير اتجاه الشاشة. هذا يعني أنه يتم استدعاء التابع `onCreate()` مرة أخرى، ويتم إعادة تحميل التخطيط بأكمله. في حين أن هذا يمكن أن يكون مفيدًا لإعادة هيكلة واجهة المستخدم بالكامل بناءً على الاتجاه، إلا أنه قد يكون غير فعال إذا كنت تحتاج فقط إلى تعديل التخطيط بشكل طفيف.
لمنع إعادة إنشاء النشاط، يمكنك الإعلان عن أن نشاطك يتعامل مع تغيير التكوين `orientation` في ملف `AndroidManifest.xml`:
<activity
android:name=".MyActivity"
android:configChanges="orientation|screenSize"
... >
</activity>
بإضافة `orientation` و `screenSize` (مهم لمستوى API 13 وما فوق)، فإنك تخبر النظام بأن نشاطك سيتعامل مع تغييرات الاتجاه بنفسه. عند تدوير الشاشة، سيتم استدعاء التابع `onConfigurationChanged()`.
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Check the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}
داخل `onConfigurationChanged()`، يمكنك تحديث واجهة المستخدم بناءً على الاتجاه الجديد. هذا النهج أكثر كفاءة من إعادة إنشاء النشاط لأنه يتجنب تحميل الموارد وتضخيم التخطيط بشكل غير ضروري.
ب. حفظ واستعادة حالة النشاط
حتى لو تعاملت مع تغيير التكوين بنفسك، قد لا تزال بحاجة إلى حفظ واستعادة حالة النشاط. على سبيل المثال، إذا كان نشاطك يحتوي على حقل نصي، فسترغب في الحفاظ على النص الذي أدخله المستخدم عند تدوير الشاشة.
يمكنك استخدام التابع `onSaveInstanceState()` لحفظ حالة النشاط والتابع `onRestoreInstanceState()` لاستعادتها.
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString("my_text", myTextView.getText().toString());
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
String myText = savedInstanceState.getString("my_text");
myTextView.setText(myText);
}
بدلاً من ذلك، يمكنك استخدام ViewModels مع SavedStateHandle لإدارة واستمرار البيانات المتعلقة بواجهة المستخدم عبر تغييرات التكوين، وهو نهج أحدث وموصى به.
ج. التخطيطات البديلة
يسمح لك أندرويد بتوفير ملفات تخطيط مختلفة لاتجاهات الشاشة المختلفة. يمكنك إنشاء ملفات تخطيط منفصلة في الدلائل `res/layout-land/` و `res/layout-port/`. عند تدوير الشاشة، سيقوم أندرويد تلقائيًا بتحميل ملف التخطيط المناسب.
هذا النهج مفيد عندما تحتاج واجهة المستخدم إلى أن تكون مختلفة بشكل كبير في الوضعين الأفقي والرأسي. على سبيل المثال، قد ترغب في عرض تخطيط من جزأين في الوضع الأفقي وتخطيط من جزء واحد في الوضع الرأسي.
د. استخدام ConstraintLayout
ConstraintLayout هو مدير تخطيط قوي يسمح لك بإنشاء تخطيطات مرنة وقابلة للتكيف. باستخدام ConstraintLayout، يمكنك تحديد قيود تحدد كيفية وضع العروض بالنسبة لبعضها البعض وللتخطيط الأصلي. هذا يسهل إنشاء تخطيطات تتكيف مع أحجام الشاشات والاتجاهات المختلفة.
2. iOS
يوفر iOS أيضًا آليات للتعامل مع تغييرات اتجاه الشاشة. إليك بعض الأساليب الشائعة:
أ. التخطيط التلقائي (Auto Layout)
التخطيط التلقائي هو نظام تخطيط قائم على القيود يسمح لك بتحديد قواعد لكيفية وضع العروض وتحديد حجمها. تضمن قيود التخطيط التلقائي أن تتكيف واجهة المستخدم الخاصة بك مع أحجام الشاشات والاتجاهات المختلفة.
عند استخدام التخطيط التلقائي، تقوم عادةً بتحديد قيود تحدد العلاقات بين العروض. على سبيل المثال، قد تقيد زرًا ليكون في المنتصف أفقيًا وعموديًا داخل العرض الأصلي. عند تدوير الشاشة، يقوم محرك التخطيط التلقائي بإعادة حساب مواضع وأحجام العروض تلقائيًا لتلبية القيود.
ب. فئات الحجم (Size Classes)
فئات الحجم هي طريقة لتصنيف أحجام الشاشات والاتجاهات. يحدد iOS فئتي حجم: `Compact` و `Regular`. يمكن أن يكون للجهاز فئات حجم مختلفة لعرضه وارتفاعه. على سبيل المثال، يحتوي جهاز iPhone في الوضع الرأسي على فئة حجم عرض `Compact` وفئة حجم ارتفاع `Regular`. في الوضع الأفقي، غالبًا ما يكون لديه ارتفاع `Compact` وعرض `Compact` أو `Regular` اعتمادًا على الطراز.
يمكنك استخدام فئات الحجم لتخصيص واجهة المستخدم الخاصة بك بناءً على حجم الشاشة واتجاهها. على سبيل المثال، قد ترغب في عرض مجموعة مختلفة من العروض أو استخدام خطوط مختلفة لفئات الحجم المختلفة.
يمكنك تكوين قيود مختلفة وحتى تثبيت/إلغاء تثبيت العروض بناءً على فئات الحجم مباشرة في Interface Builder أو برمجيًا.
ج. توابع دوران وحدة التحكم بالعرض (View Controller Rotation Methods)
يوفر iOS عدة توابع في فئة UIViewController يتم استدعاؤها عند دوران الجهاز:
viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator): يُستدعى قبل تغيير حجم عرض وحدة التحكم في العرض للانتقال.viewWillLayoutSubviews(): يُستدعى مباشرة قبل أن يقوم عرض وحدة التحكم في العرض بتخطيط عروضه الفرعية.viewDidLayoutSubviews(): يُستدعى مباشرة بعد أن يقوم عرض وحدة التحكم في العرض بتخطيط عروضه الفرعية.
يمكنك تجاوز هذه التوابع لإجراء تعديلات تخطيط مخصصة عند تدوير الشاشة.
د. مركز الإشعارات (Notification Center)
يمكنك الاستماع لإشعارات تغيير الاتجاه باستخدام مركز الإشعارات:
NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: UIDevice.orientationDidChangeNotification, object: nil)
@objc func orientationChanged() {
if UIDevice.current.orientation.isLandscape {
print("Landscape")
} else {
print("Portrait")
}
}
3. تطوير الويب (HTML, CSS, JavaScript)
في تطوير الويب، يمكنك استخدام استعلامات الوسائط في CSS وجافاسكريبت للتعامل مع تغييرات اتجاه الشاشة.
أ. استعلامات الوسائط في CSS
تسمح لك استعلامات الوسائط بتطبيق أنماط مختلفة بناءً على حجم الشاشة والاتجاه وخصائص أخرى. يمكنك استخدام ميزة الوسائط `orientation` لاستهداف اتجاهات محددة.
/* Portrait orientation */
@media (orientation: portrait) {
body {
background-color: lightblue;
}
}
/* Landscape orientation */
@media (orientation: landscape) {
body {
background-color: lightgreen;
}
}
يمكنك استخدام استعلامات الوسائط لتعديل التخطيط والخطوط والأنماط الأخرى بناءً على الاتجاه.
ب. جافاسكريبت (JavaScript)
يمكنك استخدام جافاسكريبت لاكتشاف تغييرات اتجاه الشاشة وتنفيذ إجراءات مخصصة. توفر واجهة برمجة التطبيقات `screen.orientation` معلومات حول الاتجاه الحالي.
function handleOrientationChange() {
if (screen.orientation.type === "landscape-primary" || screen.orientation.type === "landscape-secondary") {
console.log("Landscape");
} else if (screen.orientation.type === "portrait-primary" || screen.orientation.type === "portrait-secondary") {
console.log("Portrait");
} else {
console.log("Unknown orientation");
}
}
window.addEventListener("orientationchange", handleOrientationChange);
بدلاً من ذلك، يمكنك استخدام واجهة برمجة التطبيقات `matchMedia` مع استعلامات الوسائط:
const landscapeMediaQuery = window.matchMedia("(orientation: landscape)");
function handleOrientationChange(event) {
if (event.matches) {
console.log("Landscape");
} else {
console.log("Portrait");
}
}
landscapeMediaQuery.addEventListener("change", handleOrientationChange);
يمكن استخدام جافاسكريبت لتعديل التخطيط ديناميكيًا، أو تحميل موارد مختلفة، أو تنفيذ إجراءات أخرى بناءً على الاتجاه.
ج. أطر عمل التصميم المتجاوب
توفر أطر عمل مثل Bootstrap و Foundation و Materialize CSS دعمًا مدمجًا للتصميم المتجاوب، مما يسهل إنشاء تخطيطات تتكيف مع أحجام الشاشات والاتجاهات المختلفة. تستخدم هذه الأطر عادةً نظام شبكي واستعلامات وسائط لإنشاء واجهات مستخدم مرنة ومتجاوبة.
أفضل الممارسات للتعامل مع اتجاه الشاشة
إليك بعض أفضل الممارسات التي يجب مراعاتها عند التعامل مع تغييرات اتجاه الشاشة:
- تجنب إعادة إنشاء النشاط/وحدة التحكم في العرض غير الضرورية: إذا أمكن، تعامل مع تغيير التكوين بنفسك لتجنب الحمل الزائد لإعادة إنشاء النشاط أو وحدة التحكم في العرض.
- حفظ واستعادة الحالة: احفظ واستعد دائمًا حالة النشاط/وحدة التحكم في العرض لمنع فقدان البيانات. استخدم ViewModels لإدارة حالة أكثر قوة.
- استخدام Auto Layout أو ConstraintLayout: تسهل أنظمة التخطيط هذه إنشاء تخطيطات مرنة وقابلة للتكيف.
- الاختبار على أجهزة متعددة: اختبر تطبيقك على مجموعة متنوعة من الأجهزة ذات أحجام الشاشات والاتجاهات المختلفة لضمان عمله بشكل صحيح.
- مراعاة إمكانية الوصول: تأكد من أن تطبيقك يظل متاحًا للمستخدمين ذوي الإعاقة عند تدوير الشاشة.
- توفير إشارات بصرية واضحة: إذا تغيرت واجهة المستخدم بشكل كبير عند تدوير الشاشة، فقدم إشارات بصرية واضحة لمساعدة المستخدمين على فهم التغييرات.
- تجنب فرض اتجاه معين (إلا للضرورة): اسمح للمستخدمين باستخدام أجهزتهم في اتجاههم المفضل كلما أمكن ذلك. يمكن أن يكون فرض اتجاه معين محبطًا وغير مريح. لا تقم بقفل الاتجاه إلا إذا كان ضروريًا لوظيفة التطبيق (على سبيل المثال، لعبة تتطلب الوضع الأفقي). إذا قمت بقفل الاتجاه، فوضح السبب للمستخدم بوضوح.
- التحسين من أجل الأداء: قلل من كمية العمل الذي يجب القيام به عند تدوير الشاشة لتجنب مشكلات الأداء.
- استخدام الوحدات النسبية: عند تحديد الأحجام والمواضع في تخطيطك، استخدم الوحدات النسبية (مثل النسب المئوية، `dp`، `sp`) بدلاً من الوحدات المطلقة (مثل البكسل) لضمان توسع واجهة المستخدم بشكل صحيح على أحجام الشاشات المختلفة.
- الاستفادة من المكتبات وأطر العمل الحالية: استفد من المكتبات وأطر العمل الحالية التي توفر دعمًا للتصميم المتجاوب والتعامل مع اتجاه الشاشة.
قفل الاتجاه وتجربة المستخدم
بينما من الأفضل عمومًا السماح للمستخدمين بتدوير أجهزتهم بحرية، هناك مواقف قد ترغب فيها في قفل اتجاه الشاشة. على سبيل المثال، قد يقوم مشغل فيديو بملء الشاشة بقفل الاتجاه إلى الوضع الأفقي للحصول على عرض مثالي.
ومع ذلك، من المهم استخدام قفل الاتجاه باعتدال وتقديم سبب واضح للمستخدم. يمكن أن يكون فرض اتجاه معين محبطًا ويمكن أن يجعل تطبيقك أقل قابلية للوصول.
كيفية قفل اتجاه الشاشة
أندرويد (Android)
يمكنك قفل اتجاه الشاشة في أندرويد عن طريق تعيين السمة `screenOrientation` في ملف `AndroidManifest.xml`:
<activity
android:name=".MyActivity"
android:screenOrientation="landscape"
... >
</activity>
يمكنك أيضًا قفل الاتجاه برمجيًا:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
iOS
في iOS، يمكنك تحديد الاتجاهات المدعومة في ملف `Info.plist`. يمكنك أيضًا تجاوز التابع `supportedInterfaceOrientations` في وحدة التحكم في العرض الخاصة بك:
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .landscape
}
اعتبارات عالمية
عند التصميم لجمهور عالمي، ضع في اعتبارك ما يلي فيما يتعلق باتجاه الشاشة:
- التخطيطات من اليمين إلى اليسار (RTL): ضع في اعتبارك كيف ستتكيف واجهة المستخدم الخاصة بك مع اللغات التي تُكتب من اليمين إلى اليسار. بعض اللغات، مثل العربية والعبرية، تُكتب من اليمين إلى اليسار. تأكد من أن تخطيطك ينعكس بشكل صحيح في وضع RTL. غالبًا ما يوفر Auto Layout و ConstraintLayout دعمًا مدمجًا لتخطيطات RTL.
- التفضيلات الثقافية: كن على دراية بالتفضيلات الثقافية المتعلقة باستخدام الجهاز. بينما يعتاد معظم المستخدمين على الوضعين الرأسي والأفقي، قد يكون لدى بعض الثقافات تفضيلات دقيقة. يمكن أن يوفر الاختبار مع مستخدمين من مناطق مختلفة رؤى قيمة.
- إمكانية الوصول للمستخدمين المتنوعين: أعطِ الأولوية دائمًا لإمكانية الوصول. تأكد من أن تطبيقك قابل للاستخدام من قبل الأشخاص ذوي الإعاقة، بغض النظر عن اتجاه الشاشة. يشمل ذلك توفير نص بديل للصور، وضمان تباين ألوان كافٍ، ودعم التقنيات المساعدة.
اختبار التعامل مع اتجاه الشاشة
الاختبار الشامل ضروري لضمان أن تطبيقك يتعامل مع تغييرات اتجاه الشاشة بشكل صحيح. إليك بعض النصائح للاختبار:
- استخدام المحاكيات والأجهزة الحقيقية: اختبر تطبيقك على كل من المحاكيات والأجهزة الحقيقية لتغطية نطاق أوسع من أحجام الشاشات وتكوينات الأجهزة.
- الاختبار في اتجاهات مختلفة: اختبر تطبيقك في كل من الوضعين الرأسي والأفقي، وكذلك الرأسي المعكوس والأفقي المعكوس إذا كان مدعومًا.
- الاختبار بأحجام شاشات مختلفة: اختبر تطبيقك على أجهزة ذات أحجام شاشات مختلفة لضمان أن واجهة المستخدم تتوسع بشكل صحيح.
- الاختبار بأحجام خطوط مختلفة: اختبر تطبيقك بأحجام خطوط مختلفة لضمان بقاء النص قابلاً للقراءة.
- الاختبار مع تمكين ميزات إمكانية الوصول: اختبر تطبيقك مع تمكين ميزات إمكانية الوصول مثل قارئات الشاشة لضمان بقائه متاحًا للمستخدمين ذوي الإعاقة.
- الاختبار الآلي: قم بتنفيذ اختبارات واجهة المستخدم الآلية التي تغطي تغييرات اتجاه الشاشة. يمكن أن يساعد هذا في اكتشاف التراجعات وضمان سلوك ثابت عبر الإصدارات.
الخاتمة
يعد التعامل مع اتجاه الشاشة بفعالية جانبًا حاسمًا في تطوير تطبيقات الجوال والويب. من خلال فهم التقنيات المختلفة المتاحة على كل منصة واتباع أفضل الممارسات، يمكنك إنشاء تطبيقات توفر تجربة مستخدم سلسة وممتعة، بغض النظر عن كيفية حمل المستخدم لجهازه. تذكر إعطاء الأولوية للاختبار ومراعاة الآثار العالمية لخيارات التصميم الخاصة بك لضمان أن يكون تطبيقك متاحًا وسهل الاستخدام لجمهور متنوع.