مساحة اعلانية

آخر المواضيع

التعامل مع Inheritance و Protocols

إن كنت قد قرأت الدرس السابق ستفهم الكثير من الأمور والأساسيات التي سنتحدث عنها في هذا الدرس. تحدثنا في الدرس السابق عن المتغيرات والمتحولات والدوال كما أننا قمنا بتغطية شاملة حول البرمجة كائنية التوجه OOP مع Swift.

المتطلبات
في حال أردت المتابعة في هذا الدرس عندها يجب أن يكون لديك برنامج Xcode 6.3 أو أعلى تم تنصيبه على حاسوبك يمكنك أيضاً استخدام برنامج Xcode 6.3 التجريبي وهو متوفر أيضاً في مركز Apple iOS.


والسبب في استخدام برنامج Xcode 6.3 أو أعلى هو استخدام الميزة الجديدة Swift 1.2 والتي تم تطويرها من قبل شركة آبل منذ بضعة أيام. تشرح Swift 1.2 عدداً كبيراً من الإضافات والتي تقدم لك الكثير من المزايا حتى انتهاء هذه الدروس.

تنصيب المشروع

الخطوة 01: اختيار القالب
بعد تنصيب برنامج Xcode 6.3 أو أعلى عندها يمكنك فتح مشروع جديد من خلال New > Project في قائمة File . ومن قائمة القوالب iOS Application قم بإختيار Single View Application ثم اضغط على Next .

التعامل مع Inheritance  و  Protocols

التعامل مع Inheritance  و  Protocols



الخطوة 02: تفعيل المشروع
قم بتسميه المشروع بإسم ToDo ثم أختر اسم اللغة Language إلى Swift. وأيضاً تأكد بأنك قمت بضبط Devices إلى iPhone ثم اضغط Next كما في الصورة التالية:

التعامل مع Inheritance  و  Protocols

التعامل مع Inheritance  و  Protocols

تحليل المشروع
قبل البدء بمشروع Swift. نود أن ننوه أنه إذا كنت جديداً على برنامج Xcode والتطوير بلغة iOS عندها سيكون كل ما نستخدمه هنا جديداً عليك لكن لا تقلق لأنه بعد العمل على مشروع Swift ستتعلم الكثير حول الصفوف وبنية التطبيقات.

طبعاً لا يختلف قالب المشروع الذي نقوم بالعمل عليه كما في المشروعات المنشأة على لغة Objective-C بينما الإختلاف الذي نلاحظه هو صفوف AppDelegate و ViewController .

إن كنت قد عملت مع لغة Objective-C من قبل فإنك ستلاحظ عند إنشاء المشروع لا يحتوي على ملفات كثيرة مثل ملف الترويسة (.h) أو ملفات ضمنية (.m) بينما المشروع عند العمل مع هذا التطبيق فإنه جميع هذه الأمور ستكون في صفوف موجودة ضمن ملف .swift

يحتوي المشروع الآن على ملفات Swift . واحداً لصفوف AppDelegate وهو AppDelegate.swift وأيضاً ملفاً آخر يحتوي على صفوف ViewController ضمن ملف ViewController.swift . أيضاً يحتوي المشروع على storyboard و Main.storyboard و أيضاً ملفات XIB وهي ملفات خاصة بالشاشة LaunchScreen.xib . هناك أيضاً ملفات أخرى يمكنك مشاهدتهم ضمن المشروع لكننا سنتجاهلم حالياً لأنهم غير مهمين ضمن طروحاتنا لهذه الدروس.

Inheritance
أول شيء يجب معرفته في هذا الدرس هو inheritance وهو شيء مشابه إلى البرمجة الكائنية التوجه. ومع استخدام Swift يمكنك استخدام الصفوف وبكلمات أخرى أن البنية والتعددات لا تدعم inheritance . وهذا هو الإختلاف الجوهري بين الصفوف والبنية.

UIKit
افتح ViewController.swift ثم في الأعلى ستشاهد حالة الإستيراد من أجل منصّة UIKit. تذكر بأن منصّة UIKit تقدم البنية التحتية لإنشاء دوال iOS . يمكنك مشاهدة حالة الإستيراد من خلال ViewController.swift .

import UIKit


الصفوف العليا
قمنا بإنشاء صف بإسم ViewController . وأيضاً الكلمة الموجودة بعد النقطتين (:) لا تترجم نوع الصف كما شرحنا في دروس سابقة. لكن الصف بعد النقطتين هو superclass الموجود في صف ViewController. وبكلمات أخرى ستشاهد في مثال الكود التالي:

class ViewController: UIViewController {

.......
}

وهذا يشرح أيضاً حضور حالة الإستيراد في أعلى ViewController.swift كما تم تعريفها مسبقاً في UIViewController في منصّة UIKit.

Overrides
يتضمن الصف ViewController طريقتين لكن لاحظ بأن أي واحدة من هذه الطريقتين بكلمة override. وهذا يتضمن الطريقة المعرّفة في الصف وأيضاً overridden من خلال الصف ViewController:

class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}

لا توجد خاصية البناء override مع لغة البرمجة Objective-C . في لغة Objective-C يمكنك استخدام هذه الخاصية من خلال استخدام صفوف فرعية كما أن هذه اللغة تقوم بكامل العملية بعد ذلك.

أيضاً نفس العملية مع Swift ولكن الكلمات في override تضيف طرقاً آمنة ولأنها اللواحق فيها كما في طريقة viewDidLoad مع استخدام الكلمات الدلالية. ببساطة في حال قمت بإستخدام هذه الطريقة عشوائياً فعندها سيتولد الكثير من الأخطاء. يمكنك اختبار هذه التجربة من خلال الطريقة viewDidLoad كما في الصورة التالية :

التعامل مع Inheritance  و  Protocols

التعامل مع Inheritance  و  Protocols

واجهة المستخدم

إعلان المخارج
دعونا نقوم بإضافة جدول مشاهدة وذلك لمشاهدة controller والذي سيظهر قائمة to-do. وقبل فعل ذلك تحتاج إنشاء جدول للمشاهدة لأن المخارج هي عبارة فقط عن خاصيات واضحة يمكن مشاهدتها كما يمكن ضبط بناء واجهة أيضاً. ولإستدعاء مخرج يمكنك ذلك من خلال ViewController كما أننا نضيف اللاحقة @IBOutlet إليها أيضاً.

class ViewController: UIViewController {

@IBOutlet var tableView: UITableView!
override func viewDidLoad() {

super.viewDidLoad()

}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}


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

انتظر دقيقة. تم الآن مخرج tableView بإعتباره غير ملتف وإلى الآن ليس هناك أى مشكلة. يمكن إعلان مخرج tableView بإعتبارها اختياري عن طريق استبدال علامة التعجب في المقتطف أعلاه مع علامة استفهام. ومن شأن ذلك أن يصبح على ما يرام. ومع ذلك، فإن هذا يعني أيضاً أننا بحاجة إلى بسط صراحة الملكية في كل مرة نريد الوصول إلى القيمة المخزنة في اختياري. بهذا ستصبح بسرعة مرهقة ومطول.

الإتصال بالمنفذ
ومع انتهاء إعلان المنفذ سنقوم بالإتصال به في إنشاء واجهة المستخدم . افتح Main.storyboard ثم اختر view controller ثم اختر Embed In > Navigation Controller من خلال قائمة Editor. وهذا سيقوم بتحديد view controller كملف جذري للقائمة لكن لا تقلق حول ذلك الآن.

قم بسحب UITableView من خلال مكتبة Object Library وذلك لمشاهدة controller كما يمكنك إضافة بعض التصميمات الضرورية. افتح Connections Inspector وأضبط dataSource التابعة table view لكي تتمكن من مشاهدة التحكم بشكل سليم.

التعامل مع Inheritance  و  Protocols

التعامل مع Inheritance  و  Protocols

مع استخدام Connections Inspector يمكنك اختيار view controller ثم الاتصال مع المخرج tableView لمشاهدة الجدول أيضاً الذي أضفناه تواً. وهذا سيتم الاتصال به مع مخرج tableView الموجود في صف ViewController في الجدول.
البروتوكولات
قبل البدء بإنشاء التطبيق وتشغيله نحتاج إلى إنجاز البروتوكولات UITableViewDataSource و UITableViewDelegate في صفّ ViewController وهذا أيضاً يتضمن العديد من الأمور:


الخطوة 1: توافق البروتوكول
نحتاج إخبار compiler بأن صف ViewController يتوافق مع بروتوكولات UITableViewDataSource وأيضاً UITableViewDelegate. تبدو التركيبة مشابهة تماماً للغة Objective-C :

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
...
}

الخطوة 2: إنجاز البروتوكول UITableViewDataSource
لأن البروتوكول UITableViewDelegate لم يقم بتعريف طريقة، سنقوم بإنجاز البروتوكول UITableViewDataSource. وقبل فعل ذلك سنقوم بإنشاء متغير لحفظ عناصر to-do كما في المثال التالي:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet var tableView: UITableView!
var items: [String] = []
...
}

لقد قمنا بتصريح عناصر المتغير وهو بنوع [String] كما قمنا بوضع أقواس فارغة [] وبفعل ذلك سيبدو كل شيئاً واضحاً أمامك أما الآن سنقوم بإنجاز طريقتين مطلوبتين للبروتوكول UITableViewDataSource .

طبعاً الطريقة الأولى المطلوبة هي numberOfRowsInSection(_:) وهي بسيطة جداً وهي فقط تقوم بإرجاع رقم العنصر المخزن في خاصية العناصر:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items.count
}

أما الطريقة الثانية وهي cellForRowAtIndexPath(_:) وهي تحتاج إلى شرح أكثر. وبإستخدام هذا النوع من تركيبة الكود حيث سنقوم بإنشاء عنصر اتصال من مصفوفة عناصر todo :

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

// Fetch Item
let item = self.items[indexPath.row]
// Dequeue Table View Cell
let tableViewCell = tableView.dequeueReusableCellWithIdentifier("TableViewCell", forIndexPath: indexPath) as! UITableViewCell
// Configure Table View Cell
tableViewCell.textLabel?.text = item
return tableViewCell
}

عند طلب مشاهدة الجدول أو الخلية ضمن المعرّف TableViewCell وبتمريرها في الفهرس للصف الحالي. لاحظ بأننا قمنا بتخزين الخلية في الثابت المسمى tableViewCell. ولا توجد أي حاجة لإعلان tableViewCell كمتغير.

وأيضاً معلومة مهمة هي أننا نقوم بتخفيض القيمة العائدة dequeueReusableCellWithIdentifier(_:forIndexPath:) إلى UITableViewCell بما أن تعيد نوع الكائن AnyObject حيث أن هذه العملية مشابهة لحد كبير لغة Objective-C . ولتخفيض AnyObject إلى UITableViewCell عندها نستخدم الكلمة الدلالية.

وفي السطر التالي قمنا بتثبيت خلية الجدول وذلك بضبط تصنيف لها مع قيمة العنصر. لاحظ بأن في Swift ومع خاصية textLabel في UITableViewCell يتم إعلانه على أنه نوع اختياري. يتم أيضاً ضبط خاصية نص التصنيف على أنه textLabel وكما يعرف أيضاً بالتسلسل الإختياري.

الخطوة 3: إعادة استخدام الخلية
هناك نوعان من الأمور التي تحتاج إلى فرز قبل إنشاء التطبيق. أولاً نحن بحاجة لمعرفة مشاهدة الجدول أنه يحتاج إلى استخدام فئة UITableViewCell لإنشاء خلايا جديدة عند عرض الجدول. ونحن نفعل ذلك بواسطة استدعاء registerClass (_: forCellReuseIdentifier :)، ويمر في فئة UITableViewCell وإعادة استخدام المعرّف الذي استخدمناه في وقت سابق، "TableViewCell" ثم قم بتحديث طريقة viewDidLoad كما في المثال التالي:

override func viewDidLoad() {
super.viewDidLoad()
// Register Class for Cell Reuse

self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")
}

الخطوة 4: إضافة عناصر
في الوقت الراهن ليس لديك أي عناصر لإظهارها في طريقة عرض الجدول. يتم حل هذا بسهولة عن طريق تزويد خاصيات العناصر مع عدد قليل من عناصر المهام. هناك عدة طرق لتحقيق ذلك. لقد اخترت تزويد خاصيات العناصر في طريقة viewDidLoad كالتالي:
override func viewDidLoad() {
super.viewDidLoad()
// Populate Items
self.items = ["Buy Milk", "Finish Tutorial", "Play Minecraft"]
// Register Class for Cell Reuse
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")
}

6: البناء والتشغيل
حان الوقت الآن لبدء العمل بالتطبيق وتشغيله. اختر Run من خلال قائمة Xcode's Product ثم اضغط على Command-R. إن كنت تستخدم Swift 1.2 عندها ستنتهي بالنتيجة كما في الصورة التالية:

التعامل مع Inheritance  و  Protocols

التعامل مع Inheritance  و  Protocols

لاحظ بأننا أضفنا العنوان To Do في أعلى المشاهدة في شريط الأدوات. يمكنك فعل نفس الشيء من خلال ضبط خاصية العنوان للطرق ViewController و viewDidLoad كالتالي:

override func viewDidLoad() {
super.viewDidLoad()
// Set Title
self.title = "To Do"
// Populate Items
self.items = ["Buy Milk", "Finish Tutorial", "Play Minecraft"]
// Register Class for Cell Reuse
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "TableViewCell")
}

خاتمة
على الرغم من أنك قمت بإنشاء تطبيق إلا أنك تعلمت الكثير من الأمور. لقد تحدثنا عن طرق مختلفة مثل inheritance أو overriding كما أننا قمنا بتغطية أنواع البروتوكولات وخاصة البروتوكول UITableViewDataSource في الصفّ ViewController. وأيضاً تعلمنا أن أغلب ما نستخدمه من برمجة هو نفسه متعلق بلغة Objective-C.

الكــاتــب

    • مشاركة

ليست هناك تعليقات:

جميع الحقوق محفوظة لــ الشبح للمعلوميات 2019 ©