واحدة من أشهر المميزات الجديدة التي قدمت من نظام التشغيل iOS 8 هي امكانية أنشاء بعض أنواع الملحقات. سنقوم بأرشادك خلال عملية أنشاء widget خاص لمركز الاعلام . لكن أولا دعونا نستعرض بإيجاز بعض المواضيع حول ملحقات وفهم المفاهيم الهامة التي تقف خلف الwidget .
1- ما هي الملحقات (extension):
هو غرض ثنائي خاص وهو ليس تطبيق كامل , بل يحتتاج الى أحتواءه على تطبيق ليتم توزيعه ويمكن ان يكون تطبيقك الخاص , الذي يمكن ان يحتوي على ملحق واحد او اكثر , أو واحد تم أنشاؤه حديثا .
على الرغم ان الملحق لا يتم توزيعه بشكل منفصل بل يمتلك محتواه الخاص .
بدأت الملحقات وتم السيطرة عليها عن طريق التطبيق المضيف لها . و كمثال يمكن ان يكون Safari . اذا كنت أنشأت ملحق مشترك أو نظام تطبيق يومي يدعم مركز الاعلام و الـ widget .
لأنشاء ملحق , تحتاج لآضافه هدف لمشروع الخاص بمحتوى التطبيق . يتم توفير القوالب عن طريق Xcode التي تشمل اطار عمل مناسب لكل نقطه ملحقة . يسمح للتطبيق بالتفاعل مع و متابعة السياسة الصحيحة من التطبيق المضيف .
2- نقطه المحلق اليومي :
الملحقات التي تنشأ كنقطة للملحق اليومي تسمى widget . وتهدف لتوفير وصول سريع وسهل الى المعلومات. ويكون هناك رابط الـ widget الى اطار مركز الاعلام .
من المهم ان تقوم بتصميم الـ widget والتي تكون بسيطة و مركزه على واجهه المستخدم , لانه التفاعل الزائد يسبب مشاكل . كذلك يجب ملاحظة انك لا تحتاج الوصول الى لوحه التحكم Keyboard.
من المتوقع ان يكون أداء بشكل جيد ويحافظ على محتواه أثناء التحديث بالنسبه للـ widget . حيث ان الاداء هي نقطه مهمه للنظر اليها , تحتاج الـ widget الخاص بك ان تكون على الاستعداد بسرعه و تستخدم المصادر بحكمة وهذا يجنبنا البطئ بشكل تام , على سبيل المثال يقوم النظام بأنهاء الwidget التي تستخدم ذاكرة بشكل كبير . كذلك انها بحاجة إلى أن تكون بسيطة وتركز على المحتوى الذي يتم عرض. وهذه نظرية كافيه لحد الان .
لنبدأ بأنشاء widget خاصه يومية . والتي نقوم بأنشاءها حاليا هي لعرض معلومات حول أستخدام القرص , تشمل شريط عمليات ليدعم واجهه مرئيه سريعة للمستخدم . أثناء ذلك سنغطي على أهم المبادئ لملحقات نظام التشغيل iOS 8
3- أعداد الهدف :
الخطوة الأولى : إعداد المشروع
أذا كنت تريد بناء الـ widget كملحق لتطبيق موجود , أبدأ بفتح مشروع Xcode الخاص بك , واقفز للخطوة الثانية .
أما اذا كنت تبدأ من الصفر مثلي تماما , اذن عليك اولا ان تنشئ تطبيق محتوى .
أفتح Xcode ثم File قم بأختيار New > Project . سوف نستخدم اللغه البرمجية Objective-C و قالب عرض تطبيقي مفرد للبدايه منه
الخطوة الثانية: أضافة هدف جديد
قم بفتح قائمة الفايل ثم أختار New > Target في صنف تطبيقات الملحقات (Application Extension) , ثم اختار قالب Today Extensio
ستلاحظ ان المشروع الذي يتم اضافة الهدف اليه هوالمشروع الذي نعمل عليه والذي يتضمن ملحقات الحتوى . كذلك لاحظ أن المحلقات تمتلك باقة متميزة تستند على واحده من تطبيقات المحتوى , com.tutsplus.Today.Used-Space.
اضغط على Next , اعطي للـ widget أسما , مثلا أستخدم Space , ثم أضغط على Finish , لأنشاء هدف جديد .
Xcode ينشئ نظام جديد لك , قم بالضغط على زر تفعيل للمتابعة .
يقوم Xcode بأنشاء مجموعة جديدة للـ Widget تسمى Space Used ويضيف رقم فايل لها , IViewController هي فئه فرعية , حيث أن Xcode ليس أكثر من فئه فرعية .
إذا قمت بفتح رأس تحكم طريقة العرض في محرر التعليمات البرمجية، ستلاحظ أنه هو في الواقعUIViewController.
أذا قمت بتحديد هدف الملحق من قائمة الأهداف (Targets) , قم بفتح Build Phases tab وقم بتوسيع رابط الـثنائي مع قسم المكتبات . سترى أن الهدف الجديد مرتبط مع إطار مركز إعلام.
4- واجهه المستخدم :
الأن ستبني أساس واجهه المستخدم للـ Widget الخاصه بك . تحديد حجم الWidget يكون مهما وهناك طريقتين لأخبار النظام بكمية المساحه التي نحتاجها . الاولى بأستخدام Auto Layout , الثانية بأستخدام preferredContentSize
أن مفهوم التكيف على التخطيط يكون مناسبا للـ widget أيضا .
كما نعلم ليس أجهزة الايفون تكون مختلفه في العرض (كذلك IPAD والاجهزة المستقبلية) كذلك الـ widget تحتاج لاظهار
مضمونها بالاتجاه الأفقي . أذا كانت واجهه المستخدم يمكن وصفها مع مخطط القيود الالي , اذن هذا يكون فائدة واضحه للمطور .
ويمكن تعديل الارتفاع لاحقا بأستخدام setPreferredContentSize عند الحاجة ...
الخطوة الاولى : اضافة العناصر .
في أيعاز Attributes Inspector , حدد اللون الأبيض , و محاذاة الخط الى جهه اليمين , و حجم الملصق الى 50.0%
قم بأختيار Size to Fit Content من قائمة محرر الـ Xcode الى اعادة الحجم الملصق اذا كان صغير جدا ليناسب محتوياته . التالي , اضف UIProgressView على سبيل المثال الى جهه اليسار من الملصق و قم بتحديد موقعه كما في الصورة :
مع تحديد عرض العمليات المحددة , تغيير سمة عمليات Tint في Attributes Inspector الى الابيض و تتبع Tint الى الرمادي الداكن . وهذا سيجعل الأمر أكثر وضوحا. هذا ما تبدو جيدة حتى الآن. حان الوقت لتطبيق بعض القيود.
الخطوة الثانية : إضافة القيودقم باختيار ملصق مستطيل وأضفه الى الأعلى , اسفل وقم بتتبع القيد كما هو مبين أدناه , وتأكد من عدم تقييد هوامش المربع .
قم بأختيار العرض المتقدم و أضف top, leading, and trailing constraint , أغتنم هذه الفرصة لتغيير المسافة البادئة إلى 3 و لا تنسى ألغاء تقييد للهوامش.
لاننا قمنا بتغيير قيمة القيد الرئيسي لعرض التقدم , لدينا الان مشكلة صغيرة يجب ان نحلها .
اطار عرض التقدم لا يعكس قيود العرض التقدمي . مع اننا قمنا بتحديده .. قم بالضغط على زر Resolve Auto Layout Issue
في الاسفل و قم بأختيار Update Frameمن أخيار Views section . هذا سوف يحدث الاطار القيود .
الخطوة الثالثه : البناء والتنفيذ
حان الوقت لرؤية الWidget فعليا . مع أختيار Used Space قم بأختيار Run من قائمة Product او اضغط على Commmand-R .
للكشف عن مركز إعلام عن طريق تمرير من الجزء العلوي من الشاشة إلى الأسفل واضغط على زر تحرير في الجزء السفلي من مركز إعلام. الـ Widget الخاص بك يجب أن تتوفر لإضافتها إلى القسم في واجهة المستخدم. من خلال النقر على زر إضافة على يساره.
يجب أن يكون الملحق الخاص بنا مثل هذا الشكل
يبدو جيدة، ولكن لماذا هناك الكثير من الفضاء دون عرض التقدم والتسمية؟ أيضا فلماذا لم يحترم نظام التشغيل القيد الرئيسي للوجهة لنظر التقدم؟ كلتا القضيتين هي هوامش القياسية التي وضعتها نظام التشغيل. سوف نقوم بتغيير هذا في الخطوة التالية. نلاحظ، مع ذلك، أن الهامش الأيسر هو مرغوب فيه لأنه ينسجم وجهة نظر التقدم مع اسم القطعة . إذا كنت تدوير الجهاز أو تشغيل التطبيق على جهاز آخر، ستلاحظ أن القطعة تم تعديل حجمها بشكل صحيح. وهذا بفضل التخطيط
الخطوة الرابعة :تحديد الهامش السلفي
قم بفتح TodayViewController.m في محرر Xcodes . ستلاحظ نظرة المتحكم مطابقة لـأتفاقية NCWidgetProviding . هذا يعني اننا نحتاج لتطبيق طريقة widgetMarginInsetsForProposedMarginInsets والعودة للهوامش الخاصه عن طريق عودة هيكل UIEdgeInsets . يتم تحديث طريقة التطبيق كما يلي :
قم بتشغيل التطبيق مرة ثانية لمشاهدة النتيجة . ستظهر الـ Widget اصغر مع هوامش أقل في الاسفل . وتستطيع تخصيص هذه الهوامش لنتيجه انت تختارها فيما بعد ..
الخطوة السادسة : البناء & التنفيذقم بننفيذ التطبيق مرة أخرى . يجب ان يعرض القيمة الصحيحة لكيفية أستخدام المساحه عن طريق جهازك .
7- إضافة معلومات أكثر و حركة .على الرغم اننا نعرض حاليا المساحة المستخدمة . سيكون من المثير للأهتمام لأمتلاك أرقام القطع .لتجنب تزاحم واجهه المستخدم . سوف نقوم بعمل Widget جذابه اكثر .
أذا قام المستخدم بـ taps النسبة المؤية للملصق , تتوسع الـ widget ,تظهر ملصق جديد مع الارقام المطلقة , وهذا هدف لتعلم كيف أستخدام الحركة في Widget.
1- ما هي الملحقات (extension):
هو غرض ثنائي خاص وهو ليس تطبيق كامل , بل يحتتاج الى أحتواءه على تطبيق ليتم توزيعه ويمكن ان يكون تطبيقك الخاص , الذي يمكن ان يحتوي على ملحق واحد او اكثر , أو واحد تم أنشاؤه حديثا .
على الرغم ان الملحق لا يتم توزيعه بشكل منفصل بل يمتلك محتواه الخاص .
بدأت الملحقات وتم السيطرة عليها عن طريق التطبيق المضيف لها . و كمثال يمكن ان يكون Safari . اذا كنت أنشأت ملحق مشترك أو نظام تطبيق يومي يدعم مركز الاعلام و الـ widget .
لأنشاء ملحق , تحتاج لآضافه هدف لمشروع الخاص بمحتوى التطبيق . يتم توفير القوالب عن طريق Xcode التي تشمل اطار عمل مناسب لكل نقطه ملحقة . يسمح للتطبيق بالتفاعل مع و متابعة السياسة الصحيحة من التطبيق المضيف .
2- نقطه المحلق اليومي :
الملحقات التي تنشأ كنقطة للملحق اليومي تسمى widget . وتهدف لتوفير وصول سريع وسهل الى المعلومات. ويكون هناك رابط الـ widget الى اطار مركز الاعلام .
من المتوقع ان يكون أداء بشكل جيد ويحافظ على محتواه أثناء التحديث بالنسبه للـ widget . حيث ان الاداء هي نقطه مهمه للنظر اليها , تحتاج الـ widget الخاص بك ان تكون على الاستعداد بسرعه و تستخدم المصادر بحكمة وهذا يجنبنا البطئ بشكل تام , على سبيل المثال يقوم النظام بأنهاء الwidget التي تستخدم ذاكرة بشكل كبير . كذلك انها بحاجة إلى أن تكون بسيطة وتركز على المحتوى الذي يتم عرض. وهذه نظرية كافيه لحد الان .
لنبدأ بأنشاء widget خاصه يومية . والتي نقوم بأنشاءها حاليا هي لعرض معلومات حول أستخدام القرص , تشمل شريط عمليات ليدعم واجهه مرئيه سريعة للمستخدم . أثناء ذلك سنغطي على أهم المبادئ لملحقات نظام التشغيل iOS 8
3- أعداد الهدف :
الخطوة الأولى : إعداد المشروع
أذا كنت تريد بناء الـ widget كملحق لتطبيق موجود , أبدأ بفتح مشروع Xcode الخاص بك , واقفز للخطوة الثانية .
أما اذا كنت تبدأ من الصفر مثلي تماما , اذن عليك اولا ان تنشئ تطبيق محتوى .
أفتح Xcode ثم File قم بأختيار New > Project . سوف نستخدم اللغه البرمجية Objective-C و قالب عرض تطبيقي مفرد للبدايه منه
الخطوة الثانية: أضافة هدف جديد
قم بفتح قائمة الفايل ثم أختار New > Target في صنف تطبيقات الملحقات (Application Extension) , ثم اختار قالب Today Extensio
ستلاحظ ان المشروع الذي يتم اضافة الهدف اليه هوالمشروع الذي نعمل عليه والذي يتضمن ملحقات الحتوى . كذلك لاحظ أن المحلقات تمتلك باقة متميزة تستند على واحده من تطبيقات المحتوى , com.tutsplus.Today.Used-Space.
اضغط على Next , اعطي للـ widget أسما , مثلا أستخدم Space , ثم أضغط على Finish , لأنشاء هدف جديد .
Xcode ينشئ نظام جديد لك , قم بالضغط على زر تفعيل للمتابعة .
يقوم Xcode بأنشاء مجموعة جديدة للـ Widget تسمى Space Used ويضيف رقم فايل لها , IViewController هي فئه فرعية , حيث أن Xcode ليس أكثر من فئه فرعية .
إذا قمت بفتح رأس تحكم طريقة العرض في محرر التعليمات البرمجية، ستلاحظ أنه هو في الواقعUIViewController.
أذا قمت بتحديد هدف الملحق من قائمة الأهداف (Targets) , قم بفتح Build Phases tab وقم بتوسيع رابط الـثنائي مع قسم المكتبات . سترى أن الهدف الجديد مرتبط مع إطار مركز إعلام.
4- واجهه المستخدم :
الأن ستبني أساس واجهه المستخدم للـ Widget الخاصه بك . تحديد حجم الWidget يكون مهما وهناك طريقتين لأخبار النظام بكمية المساحه التي نحتاجها . الاولى بأستخدام Auto Layout , الثانية بأستخدام preferredContentSize
أن مفهوم التكيف على التخطيط يكون مناسبا للـ widget أيضا .
كما نعلم ليس أجهزة الايفون تكون مختلفه في العرض (كذلك IPAD والاجهزة المستقبلية) كذلك الـ widget تحتاج لاظهار
مضمونها بالاتجاه الأفقي . أذا كانت واجهه المستخدم يمكن وصفها مع مخطط القيود الالي , اذن هذا يكون فائدة واضحه للمطور .
ويمكن تعديل الارتفاع لاحقا بأستخدام setPreferredContentSize عند الحاجة ...
الخطوة الاولى : اضافة العناصر .
قم بفتح MainInterface.storyboard في محرر Xcode .ستلاحظ أن تسمية عرض "مرحبا أيها العالم" موجودة بالفعل في ضوء وحدة تحكم طريقة العرض . قم بأختياره ثم اخذفه من العرض حيث لن نستخدمه
قم بأضافة ملصق جديد للعرض وأجعلها بمحاذاة الجهه اليمنى كما مبين في الشكلفي أيعاز Attributes Inspector , حدد اللون الأبيض , و محاذاة الخط الى جهه اليمين , و حجم الملصق الى 50.0%
قم بأختيار Size to Fit Content من قائمة محرر الـ Xcode الى اعادة الحجم الملصق اذا كان صغير جدا ليناسب محتوياته . التالي , اضف UIProgressView على سبيل المثال الى جهه اليسار من الملصق و قم بتحديد موقعه كما في الصورة :
مع تحديد عرض العمليات المحددة , تغيير سمة عمليات Tint في Attributes Inspector الى الابيض و تتبع Tint الى الرمادي الداكن . وهذا سيجعل الأمر أكثر وضوحا. هذا ما تبدو جيدة حتى الآن. حان الوقت لتطبيق بعض القيود.
الخطوة الثانية : إضافة القيودقم باختيار ملصق مستطيل وأضفه الى الأعلى , اسفل وقم بتتبع القيد كما هو مبين أدناه , وتأكد من عدم تقييد هوامش المربع .
قم بأختيار العرض المتقدم و أضف top, leading, and trailing constraint , أغتنم هذه الفرصة لتغيير المسافة البادئة إلى 3 و لا تنسى ألغاء تقييد للهوامش.
اطار عرض التقدم لا يعكس قيود العرض التقدمي . مع اننا قمنا بتحديده .. قم بالضغط على زر Resolve Auto Layout Issue
في الاسفل و قم بأختيار Update Frameمن أخيار Views section . هذا سوف يحدث الاطار القيود .
الخطوة الثالثه : البناء والتنفيذ
حان الوقت لرؤية الWidget فعليا . مع أختيار Used Space قم بأختيار Run من قائمة Product او اضغط على Commmand-R .
للكشف عن مركز إعلام عن طريق تمرير من الجزء العلوي من الشاشة إلى الأسفل واضغط على زر تحرير في الجزء السفلي من مركز إعلام. الـ Widget الخاص بك يجب أن تتوفر لإضافتها إلى القسم في واجهة المستخدم. من خلال النقر على زر إضافة على يساره.
يجب أن يكون الملحق الخاص بنا مثل هذا الشكل
يبدو جيدة، ولكن لماذا هناك الكثير من الفضاء دون عرض التقدم والتسمية؟ أيضا فلماذا لم يحترم نظام التشغيل القيد الرئيسي للوجهة لنظر التقدم؟ كلتا القضيتين هي هوامش القياسية التي وضعتها نظام التشغيل. سوف نقوم بتغيير هذا في الخطوة التالية. نلاحظ، مع ذلك، أن الهامش الأيسر هو مرغوب فيه لأنه ينسجم وجهة نظر التقدم مع اسم القطعة . إذا كنت تدوير الجهاز أو تشغيل التطبيق على جهاز آخر، ستلاحظ أن القطعة تم تعديل حجمها بشكل صحيح. وهذا بفضل التخطيط
الخطوة الرابعة :تحديد الهامش السلفي
قم بفتح TodayViewController.m في محرر Xcodes . ستلاحظ نظرة المتحكم مطابقة لـأتفاقية NCWidgetProviding . هذا يعني اننا نحتاج لتطبيق طريقة widgetMarginInsetsForProposedMarginInsets والعودة للهوامش الخاصه عن طريق عودة هيكل UIEdgeInsets . يتم تحديث طريقة التطبيق كما يلي :
-(UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)margins{ margins.bottom = 10.0; return margins;}
تشغيل التطبيق مرة أخرى لمعرفة النتيجة. يجب أن تكون القطعة أصغر مع أقل الهامش عند الأسفل. يمكنك تخصيص هذه الهوامش
للحصول على النتيجة التي ترجوها فيما بعد.
للحصول على النتيجة التي ترجوها فيما بعد.
يبدو أن مظهره رائع , لكن لماذا هناك مسافات اثناء تقديم المظهر و الملصق ؟ كذلك لماذا لا يدعم القيود الموجهه للمظهر العام لتطورالعملية . ؟
لكن المسأله هي الهوامش القياسية الموجوده من ظمن نظام التشغيل . وسنقوم بتغييره في الخطوة التالية . لاحظ , بينما الهوامش
widget الموجوده على اليسار تكون مرغوب بها تكون بمحاذاة المظهر العام للعملية مع .
widget الموجوده على اليسار تكون مرغوب بها تكون بمحاذاة المظهر العام للعملية مع .
تقوم بضبط حجمها بشكل صحيح . widget أذا قمت بتدوير جهازك أو تشغيل التطبيق على أجهزة مختلفة , ستلاحظ أن الـ
. وهذا الفضل يعود الى المخطط الالي ..
الخطوة الرابعة : أصلاح الهامش السفلي.
ستلاحظ أن المظهر العام للمتحكم يطابق لبروتوكول , Xcode' من محرر
TodayViewController.m
والعودة الى هامش مخصص عن طريق العوده الى هيكل UIEdgeInsets
تحديث تطوير الطريقة كما يلي
(UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)margins
ستلاحظ أن المظهر العام للمتحكم يطابق لبروتوكول , Xcode' من محرر
TodayViewController.m
قم بفتح NCWidgetProviding
هذا يعني اننا نحتاج لتطويرطريقة widgetMarginInsetsForProposedMarginInsetsوالعودة الى هامش مخصص عن طريق العوده الى هيكل UIEdgeInsets
تحديث تطوير الطريقة كما يلي
(UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)margins
{ margins.bottom = 10.0; return margins;}
الخطوة الخامسة :قابس الارتباط (connecting Outlets)
قبل الأستمرار. لنكمل الواجهه وذلك بأضافة قابسين . أذهب الى الفايل storyboard . قم تغييره الى محرر مساعد وتأكد من أنه يعرض TodayViewController.m.
أمسك على زر Control وقم بسحب من الملصق الى واجهه المتحكم الظاهرة لأنشاء القابس للملصق , قم بتسميتها percentLabel
كرر هذه الخطوة و قم بأنشاءقابس أخر و قم بتسميته barView على سبيل المثال .
خامسا : عرض البيانات الحقيقية
سنقوم بأستخدام صف الـ NSFileManager لحساب مساحة الجهاز الموجودة . لكن كيف نقوم بتحديث الـ Widget مع هذه البيانات . ؟
لهذ السبب تأتي الطريقة NCWidgetProviding وهي بروتوكول لأنظمة التشغيل المناشدة . وتسمى هذه
الطريقة widgetPerformUpdateWithCompletionHandler: عند تحميل widget و يمكن تسميتها أيضا بالخلفية . في قضية اخرى , عندما يكون الWidget مخفي , يقوم النظام بأطلاقه و يسأل عن تحديث لخزن نقطة الانطلاق . هذه النقطة ستعرض عند عرض الWidget في المرة القادمة . عادة لفترة قصيرة الى أن يختفي الـ Widget .
وتمر البراهين في هذه الطريقة لغرض المعالجة النهائية التي يتم استدعاءها عند تحديث المحتوى أو البيانات .
تقوم الكتل بأخذ معاملات من نوع NCUpdateResult للوصف اذا كنا بحاجة لعرض المحتوى . والعكس , يقوم نظام التشغيل بالتعرف فيما اذا كان هناك عدم الحاجة لخزن لقطة جديدة .
سنقوم بأستخدام صف الـ NSFileManager لحساب مساحة الجهاز الموجودة . لكن كيف نقوم بتحديث الـ Widget مع هذه البيانات . ؟
لهذ السبب تأتي الطريقة NCWidgetProviding وهي بروتوكول لأنظمة التشغيل المناشدة . وتسمى هذه
الطريقة widgetPerformUpdateWithCompletionHandler: عند تحميل widget و يمكن تسميتها أيضا بالخلفية . في قضية اخرى , عندما يكون الWidget مخفي , يقوم النظام بأطلاقه و يسأل عن تحديث لخزن نقطة الانطلاق . هذه النقطة ستعرض عند عرض الWidget في المرة القادمة . عادة لفترة قصيرة الى أن يختفي الـ Widget .
وتمر البراهين في هذه الطريقة لغرض المعالجة النهائية التي يتم استدعاءها عند تحديث المحتوى أو البيانات .
تقوم الكتل بأخذ معاملات من نوع NCUpdateResult للوصف اذا كنا بحاجة لعرض المحتوى . والعكس , يقوم نظام التشغيل بالتعرف فيما اذا كان هناك عدم الحاجة لخزن لقطة جديدة .
الخطوة الأولى :نحتاج أولا لأنشاء بعض الخصائص لعقد مختلف القياسات الكلي , المستخدم , والحر . كذلك سنضيف ميزة للسيطرة على المساحة المستخدمة في الجهاز . وهذا يمكننا بالحصول على مرونه كبيرة فيما بعد . قم بأضافة هذه الخصائص الى ملحق الصف في TodayViewController.m.
@property (nonatomic, assign) unsigned long long fileSystemSize;
@property (nonatomic, assign) unsigned long long freeSize;
@property (nonatomic, assign) unsigned long long usedSize;
@property (nonatomic, assign) double usedRate;
الخطوة الثانية : تنفيذ
updateSizes
التالي, قم بأنشاء و تنفيذ طريقة المساعد , updateSizes, لجلب البيانات اللازمة وحساب استخدام مساحة للجهاز.
- (void)updateSizes {
// Retrieve the attributes from NSFileManager
NSDictionary *dict = [[NSFileManager defaultManager]
attributesOfFileSystemForPath:NSHomeDirectory()
error:nil];
// Set the values
self.fileSystemSize = [[dict valueForKey:NSFileSystemSize]
unsignedLongLongValue];
self.freeSize = [[dict valueForKey:NSFileSystemFreeSize]
unsignedLongLongValue];
self.usedSize = self.fileSystemSize - self.freeSize;
}
الخطوة الثالثة : التخزين المؤقت
نحن نستطيع من الاستفادة من NSUserDefaults لتخزين المساحة المستخدمة المحسوبة بين عمليات الإطلاق .
تكون دورة حياة الـ Widget قصيرة اذا قمنا بعمل تخزين مؤقت للقيم . نستطيع تنصيب واجهه المستخدم مع القيمة البدائية ثم بعد ذلك نحسب القيمة الفعلية.
ويكون هذا مفيد لتحديد فيما اذا كنا بحاجة لتحديث انطلاق الـ widget ام لا , لنقوم الان بأنشاء طريقتين تكون ملاءمة للوصول الى قاعدة بيانات المستخدم الافتراضية
تكون دورة حياة الـ Widget قصيرة اذا قمنا بعمل تخزين مؤقت للقيم . نستطيع تنصيب واجهه المستخدم مع القيمة البدائية ثم بعد ذلك نحسب القيمة الفعلية.
ويكون هذا مفيد لتحديد فيما اذا كنا بحاجة لتحديث انطلاق الـ widget ام لا , لنقوم الان بأنشاء طريقتين تكون ملاءمة للوصول الى قاعدة بيانات المستخدم الافتراضية
// @implementation
- (double)usedRate
{ return [[[NSUserDefaults standardUserDefaults] valueForKey:RATE_KEY] doubleValue]; } - (void)setUsedRate:(double)usedRate { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setValue:[NSNumber numberWithDouble:usedRate] forKey:RATE_KEY]; [defaults synchronize]; }
لاحظ أنا قمنا بأستخدام macro
RATE_KEY
لذا لا تنسى أضافته للقسم العلوي من TodayViewController.m.// Macro for NSUserDefaults key
#define RATE_KEY @"kUDRateUsed"
الخطوة الرابعة: تحديث واجهه المستخدم.بما أن الـ Widget نظرة عامه مسيطرة . تكون طريقة
viewDidLoad
مكان جيد لتحديث واجهه المستخدم . ويتم أستخدام طريقة المساعد , updateInterface
للعمل . - (void)updateInterface
{
double rate = self.usedRate; // retrieve the cached value
self.percentLabel.text =
[NSString stringWithFormat:@"%.1f%%", (rate * 100)];
self.barView.progress = rate;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self updateInterface];
}
الخطوة الخامسة:الأستناد الى المعالج للأنتهاء .تميل عدد من البايتات الحرة للتغير تماما . للتأكد من أن كنا بحاجة لتحديث Widget , يجب التأكد من حساب المساحه المخزونه ثم طبق حد العتبه لـ 0.01% بالمقابل مع الرقم المضبوط للبايتات الحرة . قم بتغيير الانتهاء
widgetPerformUpdateWithCompletionHandler:
كما مبين في الشكل :- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler
{
[self updateSizes];
double newRate = (double)self.usedSize / (double)self.fileSystemSize;
if (newRate - self.usedRate < 0.0001) {
completionHandler(NCUpdateResultNoData);
} else {
[self setUsedRate:newRate];
[self updateInterface];
completionHandler(NCUpdateResultNewData);
}
}
لقد قمنا بأعادة حساب مساحة المستخدمة , اذا كانت مختلفه اختلافا كبيرا عن القيمة السابقة , قم بتخزين القيمة و تحديث الواجهه ,.
نقوم بعد ذلك بأخبار نظام التشغيل انه هناك شئ ما تغير . اما اذا لم يكن كذلك , لايوجد حاجه للقطة جديدة .
بينما لم نستخدمه في مثالنا , هنالك أيضا قيمة a NCUpdateResultFailed للاشارة الى اي خطا حاصل .
الخطوة السادسة : البناء & التنفيذقم بننفيذ التطبيق مرة أخرى . يجب ان يعرض القيمة الصحيحة لكيفية أستخدام المساحه عن طريق جهازك .
6- الخلاصة:
دعونا نستعرض دورة حياة للـ Widget الجديدة . عند فتح لوحة اليوم , محتمل ان يقوم النظام بعرض اللقطه السابقة الى ان تكون جاهزة . يتم تحميل العرض و يقوم الwidget بأسترداد التخزين المؤقت للقيمة الجديدة في NSUserDefaults ويتم أستخدامها لتحديث واجهه المستخدم .
التالي , تقوم الWidget بمطابقة تحديث مع المعالج النهائي الذي يستدعى ويقوم بأعادة أحتساب القيمة الفعلية . اذا كانت التخزين المؤقت و القيمة الجديدة لا تختلف كثيرا هنا لا نفعل شيئا .
واذا كانت القيمة الجديدة مختلفه بشكل كبير هنا نقوم بتخزين مؤقت و تحديث واجهه المستخدم وفقا لذلك.
بينما في الخلفية , يتم تشغيل Widget عن طريق نظام التشغيل و يتم تكرار نفس العملية .. اذا عادت البيانات NCUpdateResultNew , يتم أنشاء طلقه لعرض الظهور المقبل .
دعونا نستعرض دورة حياة للـ Widget الجديدة . عند فتح لوحة اليوم , محتمل ان يقوم النظام بعرض اللقطه السابقة الى ان تكون جاهزة . يتم تحميل العرض و يقوم الwidget بأسترداد التخزين المؤقت للقيمة الجديدة في NSUserDefaults ويتم أستخدامها لتحديث واجهه المستخدم .
التالي , تقوم الWidget بمطابقة تحديث مع المعالج النهائي الذي يستدعى ويقوم بأعادة أحتساب القيمة الفعلية . اذا كانت التخزين المؤقت و القيمة الجديدة لا تختلف كثيرا هنا لا نفعل شيئا .
واذا كانت القيمة الجديدة مختلفه بشكل كبير هنا نقوم بتخزين مؤقت و تحديث واجهه المستخدم وفقا لذلك.
بينما في الخلفية , يتم تشغيل Widget عن طريق نظام التشغيل و يتم تكرار نفس العملية .. اذا عادت البيانات NCUpdateResultNew , يتم أنشاء طلقه لعرض الظهور المقبل .
7- إضافة معلومات أكثر و حركة .على الرغم اننا نعرض حاليا المساحة المستخدمة . سيكون من المثير للأهتمام لأمتلاك أرقام القطع .لتجنب تزاحم واجهه المستخدم . سوف نقوم بعمل Widget جذابه اكثر .
أذا قام المستخدم بـ taps النسبة المؤية للملصق , تتوسع الـ widget ,تظهر ملصق جديد مع الارقام المطلقة , وهذا هدف لتعلم كيف أستخدام الحركة في Widget.
الخطوة الاولى : تغيير واجهه المستخدم .قم بفتح MainInterface.storyboard و أختار النسبة المؤية للملصق . في Attributes Inspector أسفل جزء الـ View قم بأيجاد خيار User Interaction Enabled وقم بتمكينه.
التالي, نحتاج الى ازاله الهوامش في أسفل الملصق . تتغير المسافه الموجودة اسفل الملصق برمجيا , هذا يعني الهوامش ستكون غير موجودة .
قم بأختيار الملصق , وافتح مساحه Size يكون في Size Inspector , قم بأختيار مسافة الهامش السفلي , ثم أضغط على مسح,
تستطيع ايضا ان تحدد يدويا أرشادك الى الهوامش في الview ثم تقوم بمسحه, حاليا الملصق له مساحه هامش زائدة في الاعلى كما هو مبين في الشكل .
قم بأختيار الملصق , وافتح مساحه Size يكون في Size Inspector , قم بأختيار مسافة الهامش السفلي , ثم أضغط على مسح,
تستطيع ايضا ان تحدد يدويا أرشادك الى الهوامش في الview ثم تقوم بمسحه, حاليا الملصق له مساحه هامش زائدة في الاعلى كما هو مبين في الشكل .
قم بتحديد view controller عن طريق الضغط على اول ثلاث ايكونات في اعلى المشهد , في مساحه Size للـ Size Inspector, ثبت قيمه الارتفاع الى 106
قم بإضافة الملصق الى المظهر , كما عملنا سابقا , وثبت اللون الى أبيض في Attributes Inspector. بالاضافة الى تثبيت ارقم الخط الى 3 , والارتفاع الى 61 , و العرض الى 200 .
هذا يجب أن يكون كافيا لملائمة معلومات ثلاث خطوط , كذلك ستقوم بمحاذاة بأتجاه الاسفل و يسار الهوامش.
الخطوة الأخيرة هى لفتح مساعد المحرر وإنشاء منفذ للملصق Outlet.
الخطوة الثانية: التنصيب.
الخطوة الثانية: التنصيب.
ستتوسع الwidget في لحظة مختصرة . نستطيع خزن Boolean في
NSUserDefaults
وتحميلها تذكر الحاله السابقة , لكن , للأحتفاظ بها بسيطة , كل مرة يتم فيها تحميل الWidget سيتم أغلاقها , عند الاستفادة من النسبة المؤية للملصق تظهر المعلومات الاضافية .
لنقوم بتعريف وحدتين صغيرتين في أعلى TodayViewController.m للمساعده في الاحجام .
#define kWClosedHeight 37.0
#define kWExpandedHeight 106.0
في
وسوف تتلاشى في تفاصيل الملصق عندما يتم مراقبة النسبة المؤية للملصق
viewDidLoad
, قم بأضافه خطين , لتثبيت القيمة البدائية للأرتفاع widget و عمل تفاصيل شفافيه الملصق , وسوف تتلاشى في تفاصيل الملصق عندما يتم مراقبة النسبة المؤية للملصق
- (void)viewDidLoad {
[super viewDidLoad];
[self updateInterface];
// new
[self setPreferredContentSize:CGSizeMake(0.0, kWClosedHeight)];
[self.detailsLabel setAlpha:0.0];
}
لاحظ اننا ثبتنا قمية العرض الى 0.0 لان العرض يتم تحديده مسبقا من قبل نظام التشغيل .
الخطوة الثالثة : تحديث تفاصيل الملصق اوالتسمية . في تفاصيل الملصق . نشاهد القيمة حرة و مستخدمة , و المساحه الكلية موجودة
مع المساعدة
NSByteCountFormatter
. وقم بأضافة التطوير الاتي لعرض المسيطر-(void)updateDetailsLabel
{
NSByteCountFormatter *formatter =
[[NSByteCountFormatter alloc] init];
[formatter setCountStyle:NSByteCountFormatterCountStyleFile];
self.detailsLabel.text =
[NSString stringWithFormat:
@"Used:\t%@\nFree:\t%@\nTotal:\t%@",
[formatter stringFromByteCount:self.usedSize],
[formatter stringFromByteCount:self.freeSize],
[formatter stringFromByteCount:self.fileSystemSize]]; }
الخطوة الرابعة: التقاط اللمسات .يتم الكشف عن اللمسات بتخطي طريقة
touchesBegan:withEvent:
. الفكرة بسيطة , اينما تم الكشف , تتوسع الـ Widget و يتم تحديث تفاصيل الملصق . لاحظ ان حجم الWidget يتم تحديثه بأستدعاء setPreferredContentSize:
في عرض المسطر-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self updateDetailsLabel];
[self setPreferredContentSize:
CGSizeMake(0.0, kWExpandedHeight)];
}
الخطوة الخامسة : إضافة الحركة .على الرغم ان widget تعمل بالغرامات , يمكننا تحسين تجربة المستخدم من خلال توسيع تفاصيل الملصق أثناء توسع الwidget وهذا ممكن اذا قمنا بتنفيذ
ويتم أستدعاء هذه الطريقة عند تغير ارتفاع widget
بسبب مرور احداثيات نقل الكيان , و نستطيع احتواء حركات أضافية .
كما ترى , قمنا بتغيير قيمة الفا لتفاصيل الملصق , لكنك تستطيع اضافة اي نوع من الحركة انه تشعر يعزز تجربة المستخدم.
viewWillTransitionToSize:withTransitionCoordinator:
.ويتم أستدعاء هذه الطريقة عند تغير ارتفاع widget
بسبب مرور احداثيات نقل الكيان , و نستطيع احتواء حركات أضافية .
كما ترى , قمنا بتغيير قيمة الفا لتفاصيل الملصق , لكنك تستطيع اضافة اي نوع من الحركة انه تشعر يعزز تجربة المستخدم.
-(void)viewWillTransitionToSize:(CGSize)size
withTransitionCoordinator:
(id<UIViewControllerTransitionCoordinator>)coordinator
{
[coordinator animateAlongsideTransition:
^(id<UIViewControllerTransitionCoordinatorContext> context)
{
[self.detailsLabel setAlpha:1.0];
} completion:nil];
}
الخطوة السادسة : بناء & تنفيذالان اصبحنا جاهزين لتنفيذ التطبيق مرة أخرى . اعطه محاوله اضغط على ملصق النسبة للكشف عن تفاصيل جديدة.
خاتمة
في حين أن كل هذا المنطق قد تبدو معقدة أكثر من اللازم لهذه المهمة بسيطة، سوف تكون الآن على دراية العملية الكاملة لخلق التمديد اليوم
الحفاظ على هذه المبادئ في الاعتبار عند تصميم وبناء عنصر واجهة المستخدم. تذكر أن يبقيه بسيطة ومباشرة، ولا ننسى الأداء.
التخزين المؤقت هنا لن تكون هناك حاجة على الإطلاق مع هذه العمليات بسرعة، ولكن من المهم بصفة خاصة إذا كان لديك مكلفة معالجة القيام به. استخدام نظرك لمعرفة التحكم وتأكد من أنه يعمل لأحجام شاشة مختلفة. من المستحسن أيضا أن تتجنب تمرير وجهات النظر التمرير أو الاعتراف باللمسات المعقد.
على الرغم من أن الملحق سيكون وعاء منفصل، كما رأينا سابقا، فمن الممكن لتمكين تبادل المعلومات بين الملحق والتطبيق التي تحتوي على البيانات. يمكنك أيضا استخدام openURL NSExtensionContext في: completionHandler: مع مخطط URL مخصص لإطلاق التطبيق الخاص بك من Widget. وإذا كان رمز هو ما تحتاجه لمشاركتها مع الملحق الخاص بك، والمضي قدما في إنشاء إطار لاستخدامها في التطبيق الخاص بك والإرشاد.
.وآمل أن المعرفة المقدمة هنا تأتي فائدة عند البناء المقبل الخاص بك
ليست هناك تعليقات: