بسم الله الرحمن الرحيم
إذا كنت ممن يتعلم لغة Swift أو ممن يرغب في زيادة خبرته عموماً في مجال تطوير التطبيقات لنظام iOS حتماً ستنفعك هذه المقالة في تطوير تطبيقاتك في المستقبل, إذا لنبدأ مباشرة في صُلب الموضوع.
إذا أردت أن تقوم بإضافة Alert للمستخدم فأعتقد مباشرة أنك ستذهب لإضافة الخيار الرئيسي الذي توفره آبل طبعاً في لغة Swift و هو UIAlertContrller
لو أردنا أن نراجع بسرعة كيفية إضافة UIAlertController في Swift سوف يكون الأمر على النحو التالي:
let alert = UIAlertController(title: "Alert", message: "Delete this image", preferredStyle: .actionSheet)
alert.addAction(UIAlertAction(title: "Delete", style: .destructive, handler: { (alert) in
print("Delete button was tapped")
}))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (alert) in
print("Cancel button was tapped")
}))
present(alert, animated: true, completion: nil)
كما نعلم يوجد نمطين من رسائل التنبيه أو التحذير:
1. actionSheet
2.alert
لكن في هذه المقالة سوف نتطرق إلى النوع الأول و كيفية تصميم رسالة تحذير أو تنبيه خاصة بنا فقط عن طريق الكود و دون استخدام Storyboard
الخطوة الأولى:
إنشاء عنصر من نوع UIView ليكون هو العنصر الذي سيتم به الاستغناء عن الشكل الأساسي و لكن لأقوم بشرح الكود بشكل سريع
لقد قمت فقط بتحديد لون لهذا العنصر و أيضاً تغيير حدة الحواف الجانبية و أيضاً يتوجب عليك كتابة الكودد في السكر الثالث للعمل على الخطوة الثانة و هي إضافة Layout.
let alertView: UIView = {
let view = UIView()
view.backgroundColor = .white
view.translatesAutoresizingMaskIntoConstraints = false
view.layer.cornerRadius = 12
return view
}()
الخطوة الثانية و هي إظهار هذا العنصر داخل التطبيق و ليكن داخل ViewDidLoad
سأقوم بإعطاءه Layout سريعة بهذا الشكل
view.backgroundColor = .gray
view.addSubview(alertView)
alertView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 8).isActive = true
alertView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -8).isActive = true
alertView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -8).isActive = true
alertView.heightAnchor.constraint(equalToConstant: 180).isActive = true
شرح الكود السابق >>>
في البداية قمت بتغيير لون خلفية التطبيق لكي أتمكن من رؤية العنصر الخاص بي و من ثم يجب أن أضيف ذلك العنصر (View) إلى داخل الView الخاصة بالتطبيق ككل أو لندعوها الواجهة الرئيسية
و من ثم يجب أيضاً إعطاء هذا العنصر لكي يأخذ مكانه من واجهة البرنامج و إلا لن يكون مكانه بالشكل المراد.
السطرين الأول و الثاني و هم لأضافة حدود من جهتي اليمين و اليسار
السطر الثالث و هو لتحديد البعد من الأسفل و لكن قمت بإعطاءه قيمة مضافة إلى قيمة أو بعد المنطقة الأمنة Safe area و ذلك لنضع بالحسبان تشغيل التطبيق على أجهوة iPhone X و أحدث
أما السطر الأخير ببساطة هو لتحديد ارتفاع أو طول الـ View التي قمت بتعريفها من البداية و هي لب هذا الموضوع
الأن قم بتشغيل التطبيق و انظر إلى النتيجة:
حسناً وصلنا إلى نقطة جيدة و لكن ما زالت فارغة تماماً من أي شي سواء رسالة للمستخدم أو أي شيء آخر
===========================================================
القسم الثاني و هو أضافة عناصر على سبيل المثال Button, Label, etc
1- إضافة عنوان لهذه الرسالة سوف يتم بالشكل التالي:
let alertTitle: UILabel = {
let label = UILabel()
label.text = "Delete this image"
label.textColor = .gray
label.font = UIFont.systemFont(ofSize: 17)
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
شرح الكود السابق >>>
قمت بتعريف Label و داخل القوسين أستطيع التعديل على خصائصه على سبيل المثال: اللون, الخط, وضعية النص, لون الخلفية و إلى ما ذلك
و لا ننسَ أيضاً إضافة السطر الأخير كما شرحت الغاية منه مسبقاً
علينا الآن أن نضيف هذه العنصر الجديد أو الرسالة داخل الـ View الخاصة بنا عن طريق الأمر التالي
alertView.addSubview(alertTitle)
قم بتشغيل التطبيق الآن و انظر إلى النتيجة
تم إضافة الـ Label ولكنه غير مقيد بأية حدود
لإصلاح هذه المشكلة قم بتحديده داخل الـ View عن طريق هذا الكود
alertTitle.topAnchor.constraint(equalTo: alertView.topAnchor, constant: 8).isActive = true
alertTitle.centerXAnchor.constraint(equalTo: alertView.centerXAnchor).isActive = true
ربما ترى أن هذه الكود مختلف قليلاً إذ أننا في هذه النقطة نحتاج فقط لإضافة حد من الأعلى (السطر الأول) و ثم تعيين مكان الرسالة في المنتصف (السطر الثاني)
الآن لنقوم بتشغيل التطبيق
الأن سأقوم بإضافة العناصر التالية كما في الطريقة السابقة (لن أقوم بشرح الأمر مرة أخرى لأن الطريقة مشابهة لم شرحته سابقاً)
العنصر الثاني: message label
let alertMessage: UILabel = {
let label = UILabel()
label.text = "Do you want to delete this image?"
label.textColor = .black
label.textAlignment = .center
label.font = UIFont(name: "AvenirNext-Medium", size: 20)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
يمكنك طبعاً تغيير الخط و حجمه عوضاً عن خط النظام الأساسي
الآن للنتقل إلى إضافة Layout
alertView.addSubview(alertMessage)
alertMessage.topAnchor.constraint(equalTo: alertTitle.bottomAnchor, constant: 32).isActive = true
alertMessage.centerXAnchor.constraint(equalTo: alertView.centerXAnchor).isActive = true
من الأعلى قمت بمحاذاة الرسالة للجهة السفى من العنوان (Alert title)
في الخطوة ما قبل الأخيرة علينا إضافة أزرار للتحكم بهذه الرسالة
العنصر الثالث: زر الحذف
static let deleteBtn: UIButton = {
let button = UIButton()
button.setTitle("Delete", for: .normal)
button.setTitleColor(.white, for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 17)
button.backgroundColor = UIColor(red: 231/255, green: 76/255, blue: 60/255, alpha: 1)
button.layer.cornerRadius = 8
button.addTarget(self, action: #selector(deleteBtnTapped), for: .touchUpInside)
return button
}()
العنصر الرابع: زر الإلغاء
static let cancelBtn: UIButton = {
let button = UIButton()
button.setTitle("Delete", for: .normal)
button.setTitleColor(UIColor(red: 47/255, green: 121/255, blue: 255/255, alpha: 1), for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 17)
button.backgroundColor = UIColor(red: 239/255, green: 239/255, blue: 244/255, alpha: 1)
button.layer.cornerRadius = 8
button.addTarget(self, action: #selector(cancelBtnTapped), for: .touchUpInside)
return button
}()
عند إضافة Button يختلف الأمر قليلاً بالنسبة للخصائص و أيضاً لنجعل هذه الزر فعّال علينا ربط هذا الزر بـ Function لننفذه عن طريقه عملية معينة (على سبيل المثال حذف صورة)
و يتم ذلك بواسطة السطر الأخير من الكود السابق و داخل الـ Function لديك الحرية ي تنفيذ أي أمر تريده
@objc func deleteBtnTapped() {
print("Delete button was tapped")
}
@objc func cancelBtnTapped() {
print("Cancel button was tapped")
}
*ملحوظة يجب أن تكتب في البداية objc@ ليتم الأمر
(بعد إصدار Swift 4 تم إضافة هذا أمر)
الآن قبل أن تقوم بتشغيل التطبيق
لدنيا الآن زرين و أفضل طريقة لدمجهما معاً هي عن طريق إضافة StackView
لماذا؟
بدل أن نقوم بإضافة حدود مرتين سنختزل هذه الخطوة بكود واحد و نضمن أن الحجم سيكون مناسب داخل الـ View
=======================================================
3. العنصر الخامس:
let buttonsStackView: UIStackView = {
let stackView = UIStackView(arrangedSubviews: [deleteBtn, cancelBtn])
stackView.axis = .horizontal
stackView.distribution = .fillEqually
stackView.spacing = 16
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
*شرح الكود >>
هذا الكود وظيفته هي إنشاء StackView و إضافة عناصر داخله و هي (زر الحذف + زر الإلغاء)
السطر الثاني هي لجعل الأزرار بشكل أفقي
السطر الثالث لتقسيم المساحة بشكل متساوٍ بين الأزرار و من ثم قمت بإضافة مساحة بينهما في السطر الذي يليه
نأتي إلى الخطوة الأخير و هي إضافة الـStackView داخل الـ View بهذا الكود:
alertView.addSubview(buttonsStackView)
buttonsStackView.leftAnchor.constraint(equalTo: alertView.leftAnchor, constant: 16).isActive = true
buttonsStackView.rightAnchor.constraint(equalTo: alertView.rightAnchor, constant: -16).isActive = true
buttonsStackView.bottomAnchor.constraint(equalTo: alertView.bottomAnchor, constant: -16).isActive = true
buttonsStackView.heightAnchor.constraint(equalToConstant: 46).isActive = true
*ملحوظة عند إضافة الحدود من جهة اليسار و من الأسفل يجب عليك أن تضيف القيمة بشكل سلبي.
الآن لنرى النتيجة 👨🏻💻
أمر رائع!!
هذا ما أردناه و لكن الأمر ينقصه بعض الحركة لإضفاء روح إلى هذه الرسالة
في الواقع ما أرغب به هو بالضبط ما تراه في هذه الصورة:
ليبدو الأمر أكثر جمالية
=====================================================
لنبدأ بالجزء الثاني و هو كيفية إضافة حركة لهذه الـ View
سوف أقوم بعمل بعض التغييرات لتسهيل أمر الحركة علينا
أولاً علينا إنشاء متغير من نوع NSLayoutConstraint
وظيفة هذا المتغير هي تغيير الحد السفلي للـView للتحكم بإظهارها و إخفائها من الشاشة
var alertViewBottom: NSLayoutConstraint?
من ثم قم باستبدال هذا الكود السابق
alertView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -8).isActive = true
ليكون بهذا الشكل الجديد
alertViewBottom = alertView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 200)
alertViewBottom?.isActive = true
شرح الكود >>
قمت بإسناد القيمة كاملاً إلى المتغير و في السطر الثاني علينا أيضاً أن نفعل هذه القيمة أو هذا الحد من الأسفل ( في هذه الحالة سوف تختفي الـ View بشكل كامل لأنها أصبحت بمقدار 200 خارج الشاشة بالكامل)
في الخطوة التالية يجب إضافة زر لإظهار الرسالة و سوف يتم الأمر بشكل بسيط كالتالي
@IBAction func alertBtnTapped(_ sender: UIButton) {
alertViewBottom?.isActive = false
alertViewBottom?.constant = -16
alertViewBottom?.isActive = true
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity:
0.7, options: .curveEaseInOut, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
قمت بإضافة زر و في داخله الأوامر التالية
تعطيل الحد الأسفل من الـ View الخاصة بنا لإكمال الحركة بنجاح
من ثم إسناد قيمة جديدو و هي لإظهار الرسالة مرة أخرى
الآن في السطر الثالث سوف يتم تفعيل قيمة الحد مرة أخرى من جديد
أما في النهاية هو أمر بسيط لجعل الحركة بشكل سلس و جميل
بقي أمر واحد أخير و هو إخفاء الرسالة مرة أخرى عند الضغط على زر Cancel
@objc func cancelBtnTapped() {
alertViewBottom?.constant = 200
UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7,
initialSpringVelocity: 0.7, options: .curveEaseInOut, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
بهذا الشكل نكون قد انتيهنا 🥳
في النهاية ربما تلاحظ أننا كتبينا الكثير من الأكواد, لما لا نجمعها في Function ؟
قم بتحديد جميع الأكواد في ViewDidLoad و اضغط بالزر الأيمن
و الأن تم ترتيب الأمر أكثر من السابق 👌🏻
أرجو أن يكون الشرح قد أعجبكم.. و نلتقي في درس آخر إن شاء الله
التعليقات (0)
لايوجد لديك حساب في عالم البرمجة؟
تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !