02 هياكل البيانات: القوائم أحادية الرابط الجزء الثاني


مستوى المقال: متوسط

بسم الله الرحمن الرحيم 

السلام عليكم ورحمة الله وبركاته ...،

أولاً اعتذر جداً عن التأخر في طرح الشرح الذي كان من المفترض يكون بعد أسبوع من الموضوع السابق

تطرقنا في شرحنا السابق الى مفهوم القائمة أحادية الرابط وشرحنا استخداماته وطريقة عملها نظريا

شرحنا هذا سيكون عمليا من الدرجة الأولى بحيث سيكون كله حول الأكواد وتفصيلها.

 

١. إنشاء العقدة Node:

كما نعلم بأن Node هي الوحدة الأساسية لبناء قائمة أحادية الرابط أو القوائم بشكل عام ونستطيع بأن نصفها بأنها الحجر الذي يستخدم لبنائها.

لذلك يجب علينا بنائها ابتداءً.

public class SLLNode {
	public int info;
	public SLLNode next;
	
	public SLLNode(int i){
		this(i, null);
	}
	
	public SLLNode(int i, SLLNode n){
		this.info = i;
		this.next = n;
	}
}

هذا الكلاس والذي سمي بـ SSLNode هو الذي يصف لنا كل عقدة على حدى. 

وكل عقدة تتكون من info وهو المتغير الذي يحتوي على البيانات (المعلومة) وفي حالتنا هذه تكون البيانات من نوع int.

وكذلك next وهو عبارة عن الرابط الذي يصل العقدة الحالية بالعقدة التي تليها ومن الطبيعي أن يكون من نوع  SLLNode.

هذا الكلاس يحتوي على two Constructor وهما عبارة عن وظائف تستخدم لإنشاء العقد Nodes.

الأولى تستخدم لإنشاء عقدة لكنها لا ترتبط بأخرى كما نرى فيها فقد قمنا باستدعاء الميثود الثانية وقمنا بوضع null مكان الرابط.

أما الثانية فتنشأ عقدة ترتبط بأخرى. (قمت بتفصيلها في الموضوع السابق)

 

٢. إنشاء القائمة أحادية الرابط:

الكلاس السابق يمكننا من إنشاء عقدة واحدة لكن في هذا الكلاس سنتمكن من إنشاء قائمة كاملة تتكون من عدد من العقد Nodes.

أ. مؤشر لأول عنصر وآخر عنصر بالقائمة:

لكي نسهل عملية التنقل داخل القائمة سنقوم بإنشاء مؤشرين أحدهما يشير إلى أول عنصر بالقائمة (head: الرأس)،

والآخر يشير إلى آخر عنصر بالقائمة (tail: الذيل). هذين المؤشرين عبارة عن متغيريين من نوع SSNode.

protected SLLNode head, tail;

في بداية إنشاء القائمة (أو في حالة كانت القائمة خالية) فإن هذين العنصريين يكونان خاليين:

	public SLList(){
		head = tail = null;
	}

كما يتبين في هذه الـ Constructor.

 

ب. فحص القائمة إذا كانت خالية أو لا:

هذه الـ Method مهمة جداً ولها أستخدام في جل الـ Methods الأخرى، ومهمتها هي فحص إذا ما كانت القائمة خالية أو لا.

وتقوم بإرجاع قيمة Boolean إما true أو false.

	public boolean isEmpty(){
		return head == null;
		//or return tail == null;
	}

بكل بساطة في حال كان الرأس خالي فإن القائمة خالية كذلك، بالإمكان الإستعانة بالذيل كذلك فمن المستحيل أن يكون أحدهما خالي دون الآخر.

 

ب. إضافة عنصر جديد إلى الرأس (بداية القائمة):

	public void addToHead(int el){
    	head.next = head;
		head = new SLLNode(el);
		if (tail = null){ 
			tail = head;
		}
	}

أولا نجعل الرأس يشير إلى نفسه لكي نربط العنصر الجديد بالعنصر الأول السابق.

عندها نقوم بإنشاء عنصر Node ونجعله الرأس الجديد

في حالة كانت القائمة خالية نجعل الذيل يشير إلى نفس العنصر الذي يشير له الرأس.

ملاحظة: عندما يشير الرأس والذيل إلى نفس العنصر فهذا يعني بأن لدينا عنصر واحد فقط في القائمة.

 

ج. إضافة عنصر جديد إلى الذيل (نهاية القائمة):

	public void addToTail(int el){
		if(!isEmpty()){
			tail.next = new SLLNode(el);
			tail = tail.next;
		}else{
			head = tail = new SLLNode(el);
		}
	}

نفحص القائمة إذا كانت خالية:

- في حالة كانت غير خالية: ننشأ عنصر جديد ونجعل الذيل الحالي يشير إليه، ومن ثم نجعله الذيل الجديد.

- في حال كانت القائمة خالية: ننشأ عنصر جديد ونجعل الرأس والذيل يشيران إليه.

 

د. حذف العنصر الموجود بالرأس (أول عنصر):

	public int deleteHead(){
		int el = head.info;
		if(head == tail){
			head = tail = null;
		}else{
			head = head.next;
		}
		
		return el; 
	}

هذه الـ method تقوم بحذف العنصر الموجود بالرأس ومن ثم ترجع قيمته.

أولا نحفظ القيمة داخل متغير el لكي لا تضيع بعد حذف العنصر.

ومن ثم نفحص إذا كانت القائمة:

- تحتوي على عنصر واحد: فعندها نجعل الرأس والذيل يسيران إلى لا شيء null وتكون القائمة حينها خالية.

- تحتوي على أكثر من عنصر: فعندها نجعل العنصر الذي بعد الرأس هو الرأس الجديد، وفي هذه الحالة سيكون العنصر

لا يوجود ما يشير إليه ويحذف.

ومن ثم ترجع القيمة التي تم حذفها.

 

هـ- حذف العنصر الموجود بالذيل (آخر عنصر):

	public int deleteTail(){
		int el = tail.info;
		if(tail == head){
			head = tail = null;
		}else{
			SLLNode temp;
			for(temp = head; temp.next != tail; temp = temp.next);

			tail = temp; 
			tail.next = null;
		}
		
		return el;
	}

كما في السابق نحتفظ بقيمة العنصر لكي نقوم بإعادته بعد الإنتهاء من عملية الحذف لكن الحذف من الذيل ليس بسهولة الحذف من الرأس.

نفحص التالي:

- في حالة أن القائمة تحتوي على عنصر واحد فقط: فعندها نحذف القائمة كلها بجعل الرأس والذيل null.

- في حالة أن القائمة تحتوي على أكثر من عنصر:

أولا علينا أن نبحث عن العنصر السابق للذيل (العنصر قبل الأخير)، وذلك بأستخدام for loop قبلها علينا أن ننشأ مؤشر مؤقت باسم temp 

وفي بداية الـ loop نجعله يشير إلى الرأس، وننقله من عنصر إلى آخر إلى أن يصل إلى العنصر ما قبل الأخير وذلك بفحص إذا ما كان 

temp.next أي العنصر الذي يليه هو tail فعندها نكون وصلنا إلى العنصر ما قبل الأخير.

بعد أن نجد العنصر ما قبل الأخير نجعل الذيل الجديد ومن ثم نجعل الذيل يشير إلى null لكي يتم حذف العنصر الأخير تماماً.

 

و. طباعة جميع عناصر القائمة:

	public void printAll(){
		System.out.print("[");
		for(SLLNode temp = head; temp != null; temp = temp.next){
			System.out.print(temp.info + " ");
		}
		System.out.println("]");
	}

كما شرحنا سابقا نستخدم for loop للتنقل بين عناصر القائمة وطباعة قيمة كل عنصر على الشاشة.

 

ز. فحص وجود العنصر في القائمة أو لا:

	public boolean isInList(int el){
		if(isEmpty()){
			return false;
		}else{
			SLLNode temp;
			for(temp = head; temp.info != el && temp.next != null; temp = temp.next);
			return temp != null;
		}
	}

للبحث عن وجود قيمة داخل القائمة من عدمه يجب علينا أن نتنقل داخل القائمة عنصر بعنصر، وسنستخدم الأسلوب السابق

وهو باستخدام for loop. ولكن قبلها يجب علينا أن نتأكد من أن القائمة غير خالية.

الـ for loop ستتوقف في إحدى حالتين في حالة وجدة العنصر داخل القائمة وذلك ببطلان الشرط (tmep.info != el)

أو في حالة وصول temp إلى نهاية القائمة. 

عندها سنرجع القية المعاكسة لهذا الشرط (tmep != null) في حالة وصول الـ temp إلى نهاية القائمة بدون أن يجد العنصر

فعندا سيكون temp يساوي null وفي هذه الحالة سيرسل false أما في حالة إجاد العنصر فعندها temp لن يكون  null ويرسل true.

 

ح. حذف عنصر من القائمة:

public void delete(int el){
		if(!isEmpty() && isInList()){
			if(head == tail && head.info == el){
				head = tail = null;
			}else if(el == head.info){
				head = head.next;
			}else{
				SLLNode pre, temp;
				for(temp = head.next, pre = head; temp.info != el;
						pre = temp, temp = temp.next);
				if(temp != null){
					pre.next = temp.next;

					if(temp == tail){
						tail = pre;
					}

				}
			}
		}
	}

في حالة أردنا حذف عنصر من القائمة علينا أن نفكر في جميع الإحتمالات وهي كالتالي:

- هل القائمة غير خالية؟! وهل العنصر في القائمة ولتححق سنستخدم isEmpty و isInList، في حالة لم تكن القائمة خالية وكان العنصر بالقائمة ننتقل للخطوة التالية:

* هل القائمة تحتوي على عنصر واحد؟!: في هذه الحالة نقوم بحذف هذا العنصر ونجعل القائمة خالية.

* هل القائمة تحتوي على أكثر من عنصر والعنصر المراد حذفة بالرأس؟: عنذها نحذف الرأس كما أشرنا في الفقرة (د).

*الخيار الأخير هو أن العنصر موجود داخل القائمة: 

في هذه الحالة نحتاج للبحث عن العنصر بنفس الأسلوب السابق لكننا هنا على خلاف الخطوات السابقة نحتاج إلى متغيرين مؤقتين

أحدهما يشير إلى العنصر المراد حذفه والآخر يشير إلى العنصر الذي يسبقه. ولكي نقوم بذلك فعند إنشاء temp وهو العنصر المؤقت الذي سنبحث

عن طريقه للعنصر المراد حذفه نجعل pre العنصر الذي يسبقه وذلك كما يلي:

pre = head , temp = pre.next 

كما نعلم فنحن لسنا بحاجة لفحص الرأس فقد تأكدنا من أن العنصر ليس بالرأس. تنتهي for loop في حال إجاد العنصر المراد حذف مع العلم بأننا لن نصل إلى نهاية القائمة

لأننا تأكدنا من أن العنصر موجود في القائمة في الخطوة الأولى. وعند نهاية كل دورة من for loop نقوم بتحديث قيمتي pre and temp.

بعد ذلك نجعل الـ pre يشير للعنصر الذي يلي temp أي يشير للعنصر الذي بعد العنصر المراد حذفه عندها لن يكون هناك ما يشير إليه ويحذف.

** تأكد أخير في حال أن العنصر الذي حذفنها هو الأخير فعندها يجب أن نجعل الذيل يشير إلى null.

 

#شرح مفصل للـ for loop المستخدمة مع القوائم بشكل عام:

لأهميتها القصوى سوف أفصلها أكثر، إبتداءً بالشكل العام لها:

for (SLLNode temp = head; temp != null; temp = temp.next);

أولا نقوم بإنشاء متغير مؤقت ونسميه بأي أسم كان هذا المتغير في بداية الـ loop سيشير لأول عنصر بالقائمة

وهو الرأس head بعد ذلك يتأكد من تحقق الشرط وهو أن هذا المتغير لا يساوي null (أي أنه غير خالي)، ومن ثم

يحدث قيمة المتغير وذلك بجعله العنصر التالي له عن طريق (temp = temp.next) ومن ثم يقوم بالتأكد من الشرط مجدداً

هكذا حتى يصل إلى أن temp مساوي لـ tail وعندها يسنتقل للعنصر الذي يليه وهو في الحقيقة null لأنه tail.next دائما يساوي null

وهكذا تنتهي  for loop

ملاحظة: قمت بوضع ملفات للـ SLLNode and SLList classes في المرفقات تحتوي على تعليقات توضيحية.

 

أتمنى من الله أن أكون قد وفقت في تفصيل موضوعنا هذا

في حفظ الله إلى لقاء آخر

SLList.java

SLLNode.java

Abather

1


اراء المستخدمين


لاتوجد تعليقات لعرضها .



انشئ حساب جديد او قم بتسجيل دخولك لتتمكن من اضافه تعليق جديد

يجب ان تكون عضوا لدينا لتتمكن من التعليق

انشئ حساب جديد

سجل حسابك الجديد لدينا في الموقع بمنتهي السهولة .


سجل حساب جديد

تسجيل الدخول

هل تمتلك حساب بالفعل ؟ سجل دخولك من هنا.


سجل دخولك الان

Ads Belongs To This website

  • في هذا الدرس سنتعلم كيفية التعامل مع الtableview مع الـ Swift و كيفية إنشائه و بنائه داخل تطبيقك.
    في البداية ما هو الtableview ؟ 
    الtableview هو أداة من أدوات واجهة المستخدم التي تستخدم لعرض البيانات من خلالها. و تحديدا تستخدم في عرض البيانات التي تكون على شكل مجموعة عناصر مثل قائمة بمحتويات مطعم أو أسماء لطلاب في مدرسة..الخ 
    و الحقيقة أنه لا يكاد يتواجد تطبيق في متجر البرامج دون وجود tableview بما في ذلك التطبيقات الشهيرة كتطبيق facebook فكل البوستات الموجودة في الfacebook و التي تشاهدها في الصفحة الرئيسية عند فتح التطبيق ما هي إلا شرائح من هذا الtableview و كذلك في twitter و instegram... الخ.
    و لذلك يعتبر الtableview أحد أهم الأدوات الموجودة في برنامج الxcode  و من أكثر الأدوات استخداما في بناء التطبيقات إن لم يكن أكثرها لذلك من المهم لمبرمج التطبيقات أن يتعلم طريقة إنشائه و التعامل معه في التطبيق و ما سنقوم بعمله في هذا الدرس هو عرض قائمة لأسماء طلاب في الtableview و لذلك فلنبدأ...
     
    في البداية قم بفتح الإكسكود و قم بعمل باختيار create new xcode project ثم single view application و قم بتسميته و حفظه.

     

     
     
    الآن قم بالتوجه إلى الMain.storyboard لإضافة الtableview إلى تطبيقك.
    لإدراج الtableview توجه إلى مكتبة العناصر الموجودة على اليسار و قم بالبحث عن tableview كما ثم اسحبه إلى الشاشة كما هو موضح في الصور.
    ملاحظة: تأكد من سحبك لعنصر الtableview و ليس لعنصر الtableview controller  

     
     
     
    الآن قم بتعديل حجم الtableview ليملأ الشاشة بأكملها 

     
    قم بإضافة الconstraints كما هو موضح في الصورة
    إذا كنت لا تعلم ما هي الconstraints فيمكنك تجاهلها الآن، و لكنها باختصار طريقة لإظهار الui أو عناصر واجهة المستخدم كالtableview بشكل مناسب في جميع الشاشات المختلفة الحجم.

     
    الآن تم إضافة الtableview إلي التطبيق يمكنك عمل run و تشغيل التطبيق الآن،
    ستلاحظ وجود جدول محتويات بخلايا فارغة و الآن سنقوم بإكمال العملية لملء هذه الخانات ببيانات معينة: 

     
    إن الview controller الموجودة في الstoryboard و التي قمنا بإضافة الtableview إليها تمتلك ملف برمجي متصل بها يمكنك من كتابة الأكواد الخاصة بهذا الview controller بداخله و حتى تعرف ما هو هذا الملف البرمجي قم بالضغط على الدائرة الصفراء في زاوية الشريط العلوي للview controller ثم قم باختيار المربع من الشريط الأيمن في البرنامج ثم لاحظ خانة الcustom claass ستجد أن الclass أو ملف الكود المرتبط بهذا الview controller هو ملف ViewController و الذي تم إنشاؤه تلقائيا، لاحظ الصورة:


     
    الآن من الشريط العلوي تماما في البرنامج قم باختيار رمز الدائرتين لعرض ملف الكود ViewController بجانب الmain story board 

     
    الآن قم بالضغط على زر ctrl و قم بالسحب من الtableview الذي قمت بإضافته إلى داخل الكلاس على الجانب الآخر و قم بتسميته studentsTebleview أو namesTableview 

     

    الآن أصبح لدينا متغير بداخل الviewController باسم studentsTableview ليمثل الtableview على شكل كود.
    حتى نملأ هذا الtableview بالمحتويات فإننا نحتاج أن نخبر البرنامج أن مصدر هذه المحتويات سيكون هذا الViewController الذي قمنا بإضافة الstudentsTableview إليه، لكن كيف يتم ذلك ؟
    اذهب إلى الfunction التي تحمل اسم viewDidLoad و التي يتم استدعاؤها تلقائيا و يتم تنفيذ الكود الذي بداخلها تلقائيا بمجرد تشغيل البرنامج و اكتب بداخلها :
    override func viewDidLoad() {         super.viewDidLoad()         // Do any additional setup after loading the view, typically from a nib.         studentsTableview.dataSource = self }    
     
    و بهذا تكون قد عرّفت أن مصدر البيانات سيكون هذا الاوبجكت من الكلاس ViewController
    لكن ستلاحظ ظهور خطأ  و هذا الخطأ يظهر بسبب أن نوع المتغير الذي يجب أن يكون مصدرا لبيانات الtableview يجب أن يكون من نوع UITableViewDataSource بينما نلاحظ أن الكلاس ViewController يرث من الكلاس UIViewController و ليس من UITableViewDataSource لذلك لابد أن يرث كذلك من UITableViewDataSource و بالتالي قم بإضافة هذا إلى الكلاس ViewController ليظهر كما هو موضح في الصورة :

    كما تلاحظ ما زال هناك خطأ و هذا الخطأ بسبب عدم كتابة الfunctions التي تتطلبها الوراثة من UITableViewDataSource و عدد الfunctions التي يجب كتابتها هو ٣ دوال رئيسية
    و هم :
    - numberOfSections : و هي التي ستقوم فيها بإرجاع عدد المجموعات لتحوي التصنيفات المختلفة ( و غالبا ما تستخدم مجموعة واحدة فقط )
    - numberOfRowsInSection : و هي التي تستخدم لتحديد عدد الصفوف أو الخلايا في كل مجموعة 
    - cellForRowAtIndexPath : و هي التي تستخدم لتحديد بيانات كل خلية في الtableview 
    و لكتابة هذه الfunctions قم بكتابة العناوين الموضحة في الأعلى و سيقوم الإكمال التلقائي في البرنامج باقتراح خيارات لـإكمالها ثم اضغط على enter حالما تجد الfunction الصحيحة التي تريدها..
     
    سيكون شكل الكود بعد كتابة الfunctions كالتالي :

     
    في الfunction الأولى قم بكتابة 
    return 1 
    لتقوم بعمل مجموعة واحدة للخلايا
    في الfunction الثانية قم بكتابة
    return 7 كعدد مبدئي لإعادة ٧ صفوف في الtableview
    و في الfunction الثالثة كما هو موضح من الfunction أن هذه الfunction يجب أن تقوم بإرجاع قيمة من UITAbleviewCell و هي الشريحة التي سيتم عرضها في الtableview لذلك مبدئيا قم بكتابة  :
    let cell = UITableViewCell()         cell.textLabel?.text = "hello"         return cell  
    و ما قمنا بفعله هنا هو إنشاء cell من نوع UITableviewCell و قمنا بجعل الtext الخاص بها ليحوي كلمة hello و هذا سيطبق على كل الخلايا السبعة في الtableview و بالتالي سيكون شكل الكود كالتالي : 

    الآن قم بتشغيل البرنامج لاختبار الكود
    سيظهر لك ٧ خلايا في جدول محتويات و كلها تحتوي على كلمة hello كما يبدو في الصورة..

    أخيرا! قمنا بعمل tableview يقوم بعرض محتويات قمنا بتحديدها على الcell و لكن تبقى المشكلة في أن هذه المحتويات كلها متشابهة و لا تحوي مجموعة لأسماء الطلاب كما نريد فكيف نقوم بذلك ؟
    عادة عند التعامل مع الtableview لابد أن يكون هناك مصدر للبيانات لأخذ البيانات منه و عادة ما يكون هذا المصدر على شكل array 
    لذلك قم بعمل array من نوع [String] لتحوي أسماء الطلاب و قم بوضع الأسماء كما في الصورة أو كما تريد :
     
    الآن قم بالتوجه إلى الfunction التي تحمل الاسم numberOfRowsInSection و قم بإعادة عدد عناصر الarray بدلا من عدد ٧ العشوائي.
    return students.count
    الآن توجه إلى الfunction التي تحمل اسم cellForRowAtIndexPath و لاحظ أن هذه الfunction تحتوي على بارامتر باسم indexPath.
    في الحقيقة.. هذه الfunction يتم استدعؤها عدة مرات و ليس مرة واحدة و عدد المرات التي يتم استدعاؤها فيه يساوي عدد الصفوف التي قمت بإرجاعها في الfunction ذات اسم numberOfRowsInSection و بالتالي عدد مرات استدعائها سيكون مساويا لعدد عناصر الstudents array في هذه الحالة 
    حيث يقوم البرنامج بكل مرة بإعادة خلية لتمثل البيانات التي سيتم عرضها في ذلك الصف.
    المهم في الأمر أن البارامتر indexPath يحتوي على خاصية باسم row من نوع Int.
    و هذه الخاصية لاتحمل قيمة ثابتة في كل استدعاء للcellForRowAtIndex function و أنما تبدأ بقيمة 0 و في الاستدعاء التالي تزيد بمقدار ١ فتصبح قيمتها ١ ثم تنتقل إلى الاستدعاء التالي لتصبح قيمتها ٢ ثم ٣ ثم ٤... الخ
    حتى تنتهي عند آخر رقم و الذي يساوي حسب ما فهمنا في الأعلى عدد عناصر الstudents array ناقص واحد ( لأن العد سيبدأ من 0 )...
    لعلك بدأت تفهم الفكرة..
    يمكننا أن نعتمد على هذا المتغير لأخذ البيانات من الarray بالترتيب و إسنادها إلى الخلايا... لذلك بداخل الcellForRowAtIndex function قم بتعديل الكود ليكون كالتالي..
    let cell = UITableViewCell()         cell.textLabel?.text = students[indexPath.row]         return cell  
    و شكل الكود كاملا سيبدو كالتالي...

     
    الآن قم بتشغيل البرنامج و انظر إلى النتيجة النهائية
     

     
    إلى هنا نصل إلى نهاية الدرس و سنتناول الموضوع بطريقة متقدمة مستقبلا إن شاء الله.
     



    مستوى المقال: متوسط

    بواسطه يعرب المصطفى , في

  • بسم الله الرحمن الرحيم
    السلام عليكم ورحمة الله وبركاته
    على بركة الله تعالى نستكمل ما بدأنا به من مواضيع حول لغة Swift
    لهذا اليوم سوف نتطرق للجمل الشرطية، هذه الجمل تقوم باتخاذ قرار
    اما القيام بما داخلها او لا ويتحقق ذلك بوضع شرط (Bool) لها
    اولا: if
    خير سبيل لتوضيح المراد هو المثال لنأخذ هذا المثال:
    let a : Int = 1 if(a < 2){ print("الرقم أقل من 2") } في مثالنا هذا لدينا if الشرطية قبل الشروع في شرح معناها 
    لنتطرق لشكلها العام if الشرطية تبدء بـ if
    ومن بعدها (...) يوضع داخلهما الشرط
    ومن ثم {...} وهنا نظع الأكواد اللتي نريد القيام بها في حال تحقيق الشرط
    بكل بساطة في مثالنا السابق 
    إذا كان  a أصغر من 2 فقم بطباعة "الرقم أقل من 2"
    الشرط لدينا هنا (2 > a) 
    وهذا سيتم التحقق منه في كل مرة، اذا كان "true" فعندها 
    يتم الدخول إلى ما تحتويه if 
    اذا هذا الشرط يعتبر مفتاح لما داخل if 
    اما ما يوجد داخل {...} فمن الممكن ان يكون سطر إلي عشرات الأسطر
    الشروط من الممكن ان تكون اي نوع من الأنواع اللتي تطرقنا لها سابقاً 
    في مثالنا هذا في حال عدم تحقق الشرط سوف يهمل ما داخل if ولن يقوم بشىء
    ماذا لو اردنا ان نقوم بشيء آخر في حال عدم تحقق الشرط؟!
    هنا يأتي دور else لنأخذ هذا المثال
    if(a <= b){ ..... } else{ .... } في هذا المثال لدى if هذا الشرط(a<=b) 
    اذا تحقق هذا الشرط فعندها سنقوم بقراءة ما داخل if وإن لم يتحقق سنقوم بقراءة ما بداخل else
    واحد فقط من هذا الأكواد سيتم قراءته وليس كلهما.
    ليس هذا كل شيء لكن بإمكاننا أن نضع أكثر من شرط واحد  في عدة جمل عن طريق التالي:
    if(a < b){ print("a أكبر من b") } else if (a > b){ print("b إكبر من a") } else { print ("العددان متساويان") } كما في هذا المثال في حال اردنا وضع اكثر من شرط فإننا نستخدم else if 
    الترتيب هنا مهم سنبدأ بأول if إذا لم يتحقق شرطها نذهب لما بعدها وهكذا
    أما في حال تحقق الشرط فإننا نقوم بما داخل if ونترك جميع الشروط اللتي بعدها
    للتوضيح أكثر لنفرض بأننا نريد كتابة كود لحساب معدل طالب جامعي من اصل 4 
    سيكون الكود كما التالي:
    var grade : Double = 85.0 var outOf4 : Double = 0.0 if(grade >= 95){ outOf4 = 4 } else if (grade >= 90){ outOf4 = 3.75 } else if (grade >= 85){ outOf4 = 3.5 } else if (grade >= 80){ outOf4 = 3.0 } else if (grade >= 75){ outOf4 = 2.5 } else if (grade >= 70){ outOf4 = 2.0 } else if (grade >= 65){ outOf4 = 1.5 } else if (grade >= 60){ outOf4 = 1.0 } else if (grade < 60){ outOf4 = 0.0 } else { print ("درجة غير صحيحة") } في قطعة الكود هذه سيتم البحث بالتدريج عن الدرجة المناسبة لوضع المعدل المناسب
    في مثالنا سنبدأ بـ أول if ولن يتحقق الشرط فنذهب إلى ما بعدها وهكذا حتا نصل إلى الشرط المتحقق
    نغير قيمة outOf4 إلى القيمة الجديدة ونهمل جميع الشروط اللتي بعدها.
    قبل ان ننتقل إلى النقطة التالية لنفرض آننا نريد إجاد أصغر رقم من بين رقمين فعندها سوف
    نقوم بكتابة الكو التالي:
    var numa : Int = 7 var numb : Int = 3 var min : Int if (numa < numb){ min = numa } else{ min = numb } في هذا الكود سوف نقوم بتفحص إذا كان numa اصغر من numb في حال تحقق
    هذا الشرط سوف نقوم بوضع قيمة numa في min واللذي سيكون اصغر عدد، وإلا سنضع
    فيمة numb في min واللذي إما سيكون اصغر من numa او مساوي له.
    ماذا لو كان لدينا طريقة اسهل واقصر لنقوم بهذا الكود؟ 
    لننظر إلى هذا الكود: 
    var numa : Int = 7 var numb : Int = 3 var min : Int min = numa < numb ? numa : numb في الحقيقة هذا الكود يقوم بعمل الكود السابق تماماً بدون اي اختلاف
    لنقم ببعض التفصيل
    اولا سنضع قيمة لـ min  هذه القيمة مربوطة بشرط واللذي هو numa < numb 
    بعد انتهاء كتابة شرطنا نضع علامة استفهام و من ثم
    نضع القيمة في حال تحقق شرط بعدها : والقيمة الاخرى في حال عدم تحققه
    min = الشرط ؟ (في حال الشرط صحيح) : (في حال الشرط خاطأ)
     
    ثانياً: switch
    مثل سابقتها تستخدم switch للتحقق من شرط ما 
    شكلها العام كالتالي:
    switch(متغير){ case الشرط: case الشرط: default: } نبدأ بكتابة switch ونضع القيمة اللتي نريد التحقق منها بين القوسين
    ومن ثم نكتب الحالت اللتي نريده في case ولنا الخيار في كتابة العدد الذي نريده من الحالات
    وفي الاخير نضع الحالة الافتراضية.
    على عكس if فإن switch تقوم بالبحث عن الشرط المتحقق وعندما تجده تقوم القيام بما داخل الحالة
    ليس هذا وحسب وإنما تقوم بالقيام بما داخل جميع الحالات اللتي بعد هذه الحالة
    لنفرض ان شرطنا تحقق في case 3 عندها سيقوم الكود بالقيام بما داخل case 3 و case 4 إلى النهاية
    ولتفادي حدوث هذا نقوم بوضع break بعد نهاية كل حالة كما في التالي:
    switch (المتغير){ case a : break case b : break case c : break default : break } في هذه الحالة سيتم تنفيذ ما في داخل الحالة فقط وليس كل ما بعدها 
    كذلك نستخدم break في حال اردنا التخلص من default وكنا لا نريد وضع حالة افتراضية
    ملاحظة: الحالة الافتراضية سوف يتم قراءة ما بداخلها في حال لم يتحقق احد الحالات.
     
    الان لنأخذ هذا المثال اللذي سنقوم بتحديد المعدل عن طريق أخذ الحروف a+ , a ... f
    var grade : String = "a" var outOf4 : Double switch (grade){ case "a+" : outOf4 = 4 break case "a" : outOf4 = 3.75 break case "b+" : outOf4 = 3.5 break case "b" : outOf4 = 3.0 break case "c+" : outOf4 = 2.5 break case "c" : outOf4 = 2.0 break case "d+" : outOf4 = 1.5 break case "d" : outOf4 = 1.0 break case "f" : outOf4 = 0.0 break default: break }  
    اتمنى من آن آكون قد اوجزت في الشرح والتوضيح
    اي استفسار أنا بالخدمة واعتذر عن اي لبس قد وقعت به في اثناء الشرح
    مستوى المقال: مبتدئ

    بواسطه Abather , في

  • بسم الله الرحمن الرحيم
    السلام عليكم ورحمة الله وبركاته
    في هذا الموضوع استكمالا لما سبقه سأتطرق إلى العمليات الحسابية وعمليات المقارنة
    العمليات الحسابية:
    هناك بعض الاختلاف البسيط عند كتابة العمليات الحسابية او بالاحرى عند كتابة الرموز
    "+" :
    يختلف استخدام علامة الاضافة على حسب اختلاف نوع المتغير
    - عندما يكون المتغير عددي سواء Int او Double او غيرهما فإن العملية هنا
    هي عملية جمع  كما التالي:
    var num1 : Int = 5 var num2 : Int = 4 var num3 : Int = num1 + num2 في هذه الحالة ستكون قيمة num3 عبارة عن مجموع num1 و num2.
    - اما اذا كان المتغير نصي String فإن العملية هنا عبارة عن
    اضافة النصين إلى بعضهما البعض كما في التالي:
     
    var name : String = "Mohammed" var fullname : String = name + " Sadiq" عندما نقوم بطباعة او استخدام المتغير fullname فإن ما يطبع سيكون
    Mohammed Sadiq
    هذا بالتسبة علامة "+" اما ما تبقى من العلامات فإنها تستخدم فقط على الأعداد
    - "-" : تستخدم للطرح.
    - "*" : تستخدم للضرب.
    - "/" : تستخدم للقسمة.
    - "٪" : تستخدم لإجاد باقي القسمة لعدد ما مثلا:
    var num1 = 10%2 var num2 = 11%2 ستكون قيمة num1 هي : 0
    بينما num2 هي : 1
    ترتيب العميات الحسابية:
    المقصود هنا من من العمليات الحسابية تسبق من في حال كان هناك اكثر من عملية حسابية
    في سطر واحد ولدينا هنا ثلاث مستويات
    - في المستوى الأول "()" القوسين وهما في أعلى السلم بحيث يجب عليك
    القيام بم بين الأقواس أولاً.
    - في المستوى الثاني عمليتي "*" و "/" الضرب والقسمة.
    - والمستوى الثالث والأخير هما "-" و "+" الطرح والجمع.
    مثلا لو كانت لدينا العملية التالية:
    var num = 12 - 2 * 3 في هذه الحالة سوف نبدأ بعملية الضرب ومن ثم نقوم بعملية الطرح
    أي أن قيمة num ستكون : 6  وليست : 30
    var num = 2 * (3 + 4) في هذا المثال نبدأ بالعملية اللتي بين القوسين ومن ثم ما خارج القوسين
    وستكون قيمة num في هذه الحالة : 14
    أما في حالة اجتمعت عمليتان من نفس المستوى فببساطة نقوم
    بالعملية على حسب ترتيبها من اليسار إلى اليمين
    var num = 14 - 5 + 2 * 3 / 2 في هذا المثال لدينا عمليتين من نفس المستوى فعند إذ الترتيب يكون كالتالي
    اولآ نقوم بـ 3 * 2 = 6 وبعدها نقسم ناتجهما على 2 = 3
    عمليتنا الحسابية اصبحت كما التالي
    3 + 5 - 14
    بما ان العمليتان من نفس المستوى فنبدأ من اليسار 
    3 + 9 
    اذا قيمة num تساوي : 12
    ويفض لتفادي الخطأ وضع كل عمليتين تريد البدأ بهما او اتمامهما اولا بين قوسين.
     
    تطبيق العمليات على انواع مختلفة 
    var num1 : Int = 2 var num2 : Double = 3.5 var num3 = num1 + num2 في هذا المثال لا يمكن اتمام العملية الحسابية لأننا نقوم بها على
    متغييرين يحملان نوعين مختلفين Int و Double سيظهر لنا خطأ 
    ولحل هذا الخطأ يجب علينا تحويل احد المتغيرين إلى النوع الآخر
    var num1 : Int = 2 var num2 : Double = 3.5 var num3 = Double(num1) + num2 في المثال السابق قمنا بتحويل نوع المتغير num1 إلى Double لكي يتمثال مع num2
    بكل بساطة لتغيير نوع المتغير كل ما علينا فعله كتابة النوع المراد قبل اسم المتغير ووضع اسم المتغير بين قوسين
    (ملاحظة : نوع المتغير سوف يتم تبدليه فقط لهذه العملية أي انه سيكون على حاله num1 سيكون Int )
    عندها سيكون نوع num3 هو Double
    بإمكننا كذلك تغير نوع num2 إلى Int
    var num1 : Int = 2 var num2 : Double = 3.5 var num3 = num1 + Int(num2) لكن في هذه الحالة سيفقد num2 بعضاً من قيمة
    لأن Int سيحذف كل ما بعد الفاصلة.
    عمليات المقارنة:
    قبل الشروع في عمليات المقارنة لدينا ملاحظة يجب ان نزيح الغبار عليها 
    * علامة "=" اغلبنا يعرف بانها للمساوة بين شيئا لكن في دائرة البرمج هي مختلفة تماما
    لو لحظتم بأننا كنا نستخدم علامة "=" في جميع امثلتنا لإعطاء المتغير قيمة، إذا علامة "=" لوحدة ليست للمغارنة
    لكنها تستخدم لإعطاء المتغير قيمة او لتغيير قيمة الحالية :
    var name : String = "Mohammed" name = "Sadiq" في مثالنا هذا اعطينا للمتغير قيمة بوضع علامة "=" بعد المتغير، كذلك قمنا بتغيير قيمة المتغير 
    عن طريق كتابة اسم المتغير ومن ثم علامة "=" يتلوها القيمة الجديدة للمتغيير.
    عمليات المقارنة:
    - "==" وتستخدم للسؤل التالي "هل القيمة اللتي على اليسار تساوي القيمة اللتي على اليمين؟"
    - "=!" وتستخدم للسؤال "هل القيمتين مختلفتين؟"
    - ">" وتستخدم للسؤال "هل القيمة اللتي باليمين اكبير من اليسار؟"
    - "=>" وهي كسابقتها لكن يضاف عليها "هل القيمة اللتي باليمين اكبير من اليسار أو مساوية لها؟"
    - "<" وتستخدم للإجابة عن السؤال "هل القيمة اللتي باليمين اصغر من اليسار؟"
    - "=<" كما السابقة لكن يضاف لها "هل القيمة اللتي باليمين اصغر من اليسار أو مساوية لها؟"
    جميع هذه العمليات تعطين احد هاتين الاجابتين صحيح "true" او خاطئ "flase" 
    بإمكاننا حفظ هذه القيمة في متغيير من نوع Bool (هذا المتغير يقبل احد القيمتين فقط true or flase)
    var boolean1 : Bool = true var boolean2 : Bool = 1 == 2 var boolean3 : Bool = 4 <= 5 var boolean4 : Bool = 6 > 9 في هذا المثال لدى المتغيرات القيم التالية:
    boolean1 : صحيح
    boolean2 : خاطئة (لأن 1 لا يساوي 2)
    boolean3 : صحيح (لأن 4 اصغر من 5)
    boolean4 : خاطئة (لأن 6 ليست أكبر من 9)
    قد تبدوا هذه العمليات ليست ذات قيمة عالية في هذه
    اللحظة لكن ستتبين فائدتها فيما بعد، مع العلم بان هذه العمليات لا تنطبق فقط على 
    القيم العديدية لكنها كذلك تنطبق على النصوص.
    بما اننا تكلمنا عن عمليات المقارنة لابد بأن نعرج على العمليات المنطقية
    والعمليات المنطقية تجرى فقط على قيم المقارنة أي على المتغيرات من نوع Bool
    - "&&" وهذه العلامة تستخدم للسؤال "هل كلتا القيمتين صحيحتين؟"
    تكون صحيحة في حالة كانت القيمتين صحيحتين
    - "||" وهذه العلامة تستخدم للإجابة عن " هل أحد القيمتين صحيحة؟"
    وتكون القيمة صحيحة في حال كانت احد القيمتين صحيح
    لنشرع في المثال التالي لتكون الامور اكثر وضوحاً
    var bool1 : Bool = 1<2 && 3 == (6/2) var bool2 : Bool = 1 > 3 || 2 < 0 في هذا المثال قيمة bool1 هي true  لماذا؟
    لأن 1 اصغر من 2 و 3 تساوي (6\2) 
    اما قيمة bool2 فهي خاطئة 
    لأن 1 ليس أكبر من 3 أو 2 ليس اصغر من 0
    هذا الجدول سوف يوضح لنا هاتين العمليتين اكثر
    bool1 bool2 bool1 && bool2 bool1 || bool2 F F F F T F F T F T F T T T T T اتمنى من أن يكون هذا الشرح المتواضع كفيل بإصال ما آردت إصاله
    هذا وفي دعة الله إلى آن يوفقني الله تعالى لكتابة موضوع آخر
    أي استفسار بخصوص هذين الموضوعين لا تتردد بطحرحه
    لأجيب عليه او يجيب عليه أحد الأخوة
    مستوى المقال: مبتدئ

    بواسطه Abather , في

  • البرنامج المستخدم : xcode 8
    اللغة المستخدمة : swift 3 
    هذا الدرس هو الجزء الثاني من درس الtableview مع الـ Swift 
    إذا كنت لم تشاهد الجزء الأول فقم بمشاهدته الآن من خلال الرابط التالي :
    في الدرس السابق وصلنا في النهاية إلى هذه النتيجة..

    و هي تمثل جدول أو tableview يحوي أسماء الطلاب، و في هذا الدرس سنقوم بتطوير هذا الجدول و تحسينه ليحوي بيانات أكثر عن كل طالب و بالشكل الذي تختاره أنت كمطور. 
    إذا لنبدأ..
    الآن إضافةً لعرض أسماء الطلاب نريد عرض بيانات خاصة بهم كالعمر و رقم الجوال و سنقوم بعرض هذه البيانات في الجدول.
    و بالتالي فأن كل طالب سيكون له ٣ بيانات مختلفة متصلة به و خاصة به و هي الاسم و العمر و رقم الجوال بدلا من الاسم وحده.
    و بالتالي كيف يمكن أن نربط مجموعة من البيانات لشيء واحد فقط ؟
    لو عدنا إلى الarray التي تمثل مصدر البيانات أو الdata source للtableview و التي تحمل اسم students فسنجد أنها تحتوي على أسماء الطلاب فقط و بالتالي هي array من نوع string الآن نحن بحاجة إلى أن نربط كل اسم من هذه الأسماء مع العمر و رقم الهاتف لكل عنصر من العناصر و كأن هذه العناصر ستستبدل بمجموعة تحوي هذه البيانات معا؟
    لو فكرنا قليلا.. ما هي الوسيلة المتاحة في swift أو في معظم لغات البرمجة التي تمكنك من ربط عدة بيانات في مجموعة واحدة ؟
    الحل ببساطة هو الclass سنقوم بإنشاء كلاس خاص باسم student و سنقوم بوضع الخصائص الخاصة به معا في كلاس واحد :
    ١- قم بالذهاب إلى file ثم new ثم file   
    ٢- اختر swift file و اضغط على next 
    ٣- قم بتسميته Student و اختر create 
    ملاحظة : من المعتاد دائما البدء بحرف capital لجميع أسماء الكلاسات في المشروع
    الآن قم بأضافة الكود التالي إلى الملف : 
    //1: class Student { //2: var name:String! var age:Int! var phoneNum:Int! //3: init(name:String,age:Int,phoneNum:Int) { self.name = name self.age = age self.phoneNum = phoneNum } } في الخطوة الأولى قمنا بإنشاء الكلاس Student 
    و في الخطوة الثانية قمنا بإضافة المتغيرات الخاصة بهذا الكلاس و هي الاسم و العمر و رقم الجوال
    و أخيرا في الخطوة الثالثة قمنا بعمل الinitializer و هي الدالة التي ستستخدم لعمل كائنات أو objects من هذا الكلاس حيث ستستقبل الاسم و العمر و رقم الهاتف لتقوم بعمل أوبجكت جديد يحوي هذه المتغيرات.
     
    و الآن قم بالعودة إلى ViewController و قم بتغيير نوع الarray من String إلى Student و قم ببناء العناصر الجديدة لتكون من Students و لتبدو الarray بهذه الطريقة :
    //1 //var students : [String] = ["محمد","خالد","عمر","أحمد","سامي"] //2 var students : [Student] = [Student(name:"محمد",age:14,phoneNum:054050433), Student(name:"خالد",age:15,phoneNum:054384953), Student(name:"عمر",age:14,phoneNum:054837495), Student(name:"أحمد",age:17,phoneNum:054333874), Student(name:"سامي",age:16,phoneNum:0542030245) ] في الخطوة الأولى قمنا بتحويل الشكل القديم للarray ليكون على شكل comment ( بإمكانك مسحها نهائيا كذلك ) 
    و في الخطوة الثانية قمنا بعمل الarray الجديدة و التي تحوي objects من الStudent class و كل أوبجكت فيها له خصائص الاسم و العمر و رقم الجوال.
     
    و الآن نحن بحاجة لقراءة هذه البيانات و وضعها في الtableview.
    في الشكل السابق للarray كنا فقط بحاجة المتغير الذي يحمل اسم textLabel و الموجود بداخل الcell الخاصة بالtable view حيث نقوم بإسناد قيمة اسم الطالب لهذا المتغير.. لكن المشكلة أن هذا مجرد متغير واحد و نحن بحاجة إلى ٣ متغيرات في كل cell لتحوي الاسم و العمر و رقم الهاتف إذا مالحل ؟
    إن الcell أو الخلية التي قمنا باستخدامها هي في الحقيقة الخلية الأساسية في البرنامج و التي لا توفر لك كثير من الخيارات لذا نحن بحاجة إلى عمل cell خاصة بنا و تحوي المتغيرات التي تناسب البرنامج الذي نعمل عليه و سنقوم باستخدامها بدلا من الcell الأساسية.
    و حتى تقوم بإنشائها :
    ١- اذهب إلى file ثم new ثم file
    ٢- هذه المرة سنقوم بعمل cell خاصة بنا لكنها في النهاية ليست إلا cell ترث الخصائص الأساسية من TableViewCell و هو يمثل الكلاس الخاص بالcell الأساسية في الxcode و التي قمنا باستخدامها سابقا ( و بما أننا سنحتاج إلى الوراثة هنا فلن نقوم باختيار swift file و إنشاء كلاس عادي و إنما سنختار cocoa touch class ) ثم اضغط next 
    ٣- في مربع subclass of : قم بتحديد UITableviewCell و قم بتسميتها StudentCell و اختر next ثم create
    ٤- الآن هذا هو الكلاس الذي سيمثل الcell الجديدة و الذي سيمثل الأكواد التي ستكتب فيها.. لكن أين هي هذه الcell الجديدة في الواجهة ؟
    توجه إلى Main storyboard و قم بتحديد الخلية الموجودة في الtableview
    ملاحطة : إذا لم تكن تظهر لك أي خلية في الtableview فقم بتحديد الtableview و إضافة واحدة من شريط الخصائص كما هو موضح في الصورة التالية :

    و اجعل هذه الخلية ترث من ال class ( انظر إلى الصورة ) الذي قمنا بعمله للتو و هو StudentCell و ذلك من خلال اختيار شكل المربع ( show the identity inspector ) و من ثم كتابة الاسم في خانة class و بذلك ستمثل هذه الخلية نموذج لشكل كل الخلايا التي سيتم إنشاؤها في الtableview و ما سيجري على شكلها و تصميمها سيجري على كل الخلايا الأخرى في الtableview

    و لكن حتى تستطيع الوصول إلى هذه الخلية دون غيرها في الكود الخاص بك فأنت بحاجة لإضافة ID خاص بهذه الخلية ليميزها عن غيرها و هذا يتم من خلال تحديد الخلية ثم توجه إلى شريط الخصائص في الجانب الأيمن ستجد خاصية باسم : identifier قم بكتابة الid الذي تجده مناسبا لك مثل : studentCellId على سبيل المثال و لكن تذكره جيدا لأنك ستحتاجه وقت كتابة الكود الخاص بهذه الخلية

     
    و الآن قم بتصميم العناصر التي ستحمل بيانات الطلاب و هي تتم بكل بساطة عن طريق إضافة 3 labels للخلية و كل منها سيمثل أحد البيانات
    ملاحظة : قم بإضافة الأشكال ( labels ) و توزيعها بالطريقة التي تناسبك و لا تنس إضافة الconstraints و إذا أردت إضافتها بسرعة دون الدخول في تفاصيل الconstraints فقم بتحديد العناصر ثم قم بإضافتها كما هو موضح في الصورة :
     
     
     
    الآن نحن بحاجة لربط الlabels الموجودة في الخلية مع الكلاس الخاص بها حتى تكون لنا قدرة التحكم بها و بقيمها لذلك قم بفتح الكود في نصف الشاشة عن طريق الضغط على أيقونة الدائرتين الموجودة في الزاوية اليمنى من الشريط العلوي
    تأكد أن الملف المفتوح في النصف الخاص بالكود هو كلاس الStudentCell و إذا لم يكن فتوجه إلى الكلاس من العمود الأيسر الخاص بالملفات و اضغط على alt ثم اسم الكلاس و هو StudentCell  
    توجه الآن إلى أول label و هو الخاص بالاسم و قم بالضغط على ctrl و السحب من الlabel إلى داخل الclass و ستظهر لك نافذة تسأل عن الاسم كما في الصورة 
    قم بتسميته nameLabel و اضغط على connect 
    قم بتكرار نفس العملية للlabel الخاص بالعمر و رقم الهاتف و قم بتسميتهم ageLabel و phoneNumLabel على التوالي.
    و سيكون الشكل و الكود بهذا الشكل : 

     
    أخيرا تبقت خطوة أخيرة و هي إضافة القيم المناسبة لكل label في كل خلية و هذا سيتم من خلال الfunction التي تحمل اسم cellForRowAtIndexPath و الموجودة في الكلاس ViewController
    لذلك توجه إليها و قم بمسح الكود السابق الموجود بداخلها و استبدله بالكود التالي :
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { //1 let cell = tableView.dequeueReusableCell(withIdentifier: "studentCellId") as! StudentCell //2 cell.nameLabel.text = students[indexPath.row].name cell.ageLabel.text = String(students[indexPath.row].age) cell.phoneNumLabel.text = String(students[indexPath.row].phoneNum) return cell } في الخطوة الأولى : قمنا باستخدام الtableview و هو المتغير الذي يمثل الtableview الموجود في الstoryboard و الذي يحوي الخلية و الذي قمنا بإضافته في الدرس السابق و قمنا من خلاله باستدعاء function اسمها dequeueReusableCell  و التي تستخدم لجلب الcell من خلال الid الخاص بها و لذلك قمنا بإضافة الid الذي قمنا بإنشائه سابقا إلى الخانة الخاصة به كparameter للfunction ثم أضفنا : as! StudentCell حتى نقوم بعمل casting لهذه الcell لتصبح من نوع StudentCell 
    ملاحظة : إذا كنت لا تعلم ما هو الcasting فيمكنك تجاهله الآن و إضافة الكود كما هو و تعلمه لاحقا 
    و الأن أصبح لدينا cell من نوع StudentCell بمعنى آخر : يمكننا الآن الوصول إلى الlabels الموجودة في الStudentCell و تغيير قيمها اعتمادا على قيم العنصر في الarray و هذا ما قمنا بفعله في الخطوة الثانية و هذا الكود شبيه جدا للكود السابق الذي كان خاصا بإضافة الاسم فقط في كل indexPath من الarray باستثناء إضافة الخصائص الخاصة بكل عنصر للarray و ذلك لأن الarray الآن تحتوي على objects و أنت تريد الوصول إلى متغيرات هذا الobjects فتضيف .name للوصول للاسم مثلا و كذلك الأمر للعمر و رقم الهاتف
    لاحظ كذلك أننا قمنا بتحويل العمر و رقم الهاتف إلى قيم من نوع String و ذلك لأن القيم الأساسية لها هي في الحقيقة من نوع Int و لابد من تحويلها إلى String لتناسب نوعية المتغير text بداخل الLabel
    الآن قم بتشغيل البرنامج لتظهر لك بهذا الشكل حيث يظهر الخلية و هوي تحوي عدة بيانات متعلقة بالطالب بدلا من الاسم فقط  :

     
    إلى هنا نصل معكم إلى نهاية الدرس و أتمنى أن يكون ذا فائدة و نفع للقارئ الكريم
    و إلى اللقاء في دروس أخرى   
     
    مستوى المقال: متوسط

    بواسطه يعرب المصطفى , في

  • تقدم مجموعة برمج يوم ( ١ أبريل ) ورش عمل متنوعة للاردوينو من خلال عدة محاور تشمل التالي :
    مقدمة عن آردوينو شرح لكيفية إستخدام الحساسات مشروع قياس مستوى المياه في الخزان مشروع توجية السائقين للمواقف الفارغة مشروع تغيير زاوية ميلان الألواح الشمسية مشروع حول انترنت الأشياء (IoT) وذلك بمناسبة حدث #يوم_الاردوينو العالمي باعتماد من الموقع الرسمي ليوم اردوينو العالمي :

    وذلك في الرياض باستضافة مايكروسوفت مع وجود بث وتسجيل فيديو للورش.

    ولمشاهدة صفحة ورش العمل من برمج وللتسجيل في ورش العمل من خلال هذا الرابط :
    parmg.org/arduino-day
    ويمكنك متابعة حساب برمج في تويتر @parmg_sa للمزيد من اللقاءات والفعاليات المتعلقة بالبرمجة

    مستوى المقال: مبتدئ

    بواسطه althari , في

  • Ads Belongs To This website

    عالم البرمجة

    عالم البرمجة مقالات برمجة و دورات مجانية لإحتراف البرمجة هدفنا تبسيط البرمجة ونشرها بيد الكل بشكل ممتع ومتطور ومحدث بإستمرار لمواكبة جديد تطورات البرمجة الحديثة و المتقدمة بدون مقابل