Instantiate و Present ViewController في Swift: تحليل كامل مع أمثلة وإجابات على الأسئلة الشائعة
\n\nمرحبًا أيها الزملاء! إذا سبق لك أن واجهت مهمة إنشاء وعرض شاشة جديدة برمجيًا في تطبيق iOS باستخدام Swift، فمن المحتمل أنك تساءلت: "كيف يمكنني إنشاء ViewController من Storyboard بشكل صحيح؟"، "كيف أنقل البيانات قبل العرض؟" و"ما الفرق بين Segue و Present اليدوي؟".
\n\nهذا الموضوع هو من أكثر المواضيع شيوعًا على Stack Overflow (آلاف المشاهدات!)، وليس من دون سبب. للوهلة الأولى، يبدو كل شيء بسيطًا، ولكن الشيطان، كما هو الحال دائمًا، يكمن في التفاصيل. دعنا نحلل جميع الفروق الدقيقة حتى لا تخلط أبدًا بين instantiate viewController Swift و present viewController Swift.
\n\n1. الطريقة الأساسية: Instantiate من Storyboard
\n\nالسيناريو الأكثر شيوعًا هو أن لديك Storyboard مع متحكم تم تعيين Storyboard ID له. بدون هذا المعرف، لن تتمكن من إنشاء نسخة من المتحكم برمجيًا.
\n\nالخطوة 1: إعداد Storyboard ID
\nافتح Storyboard، واختر ViewController المطلوب، وانتقل إلى مدقق الهوية Identity Inspector (أيقونة بطاقة الهوية)، وفي حقل Storyboard ID أدخل اسمًا فريدًا، مثل DetailViewController. تأكد أيضًا من أن علامة الاختيار Use Storyboard ID نشطة.
الخطوة 2: كود instantiate و present
\nالآن في المكان المناسب من الكود الخاص بك (على سبيل المثال، عند الضغط على زر)، اكتب:
\n\nimport UIKit\n\nclass MainViewController: UIViewController {\n\n @IBAction func showDetailTapped(_ sender: UIButton) {\n // 1. الحصول على مرجع إلى Storyboard\n let storyboard = UIStoryboard(name: "Main", bundle: nil)\n \n // 2. إنشاء نسخة من المتحكم باستخدام Storyboard ID\n guard let detailVC = storyboard.instantiateViewController(withIdentifier: "DetailViewController") as? DetailViewController else {\n fatalError("فشل في العثور على المتحكم بالمعرف DetailViewController")\n }\n \n // 3. عرض المتحكم بشكل مشروط (مودالي)\n present(detailVC, animated: true, completion: nil)\n }\n}\n\nهذا مثال كلاسيكي على instantiate viewController Swift. لاحظ استخدام guard let — هذا استخراج آمن يحميك من تعطل التطبيق إذا تم إدخال المعرف بشكل خاطئ.
2. Present مقابل Push: متى نستخدم كل منهما؟
\n\nكثير من المبتدئين يخلطون بين present (العرض المشروط) و push (الدفع في مكدس التنقل). دعنا نحلل الفرق.
\n\n- \n
- Present — هو عرض مشروط. يظهر المتحكم من الأسفل (أو بحركة أخرى) ولا يرتبط بمكدس التنقل. يُستخدم للشاشات المؤقتة: تسجيل الدخول، التنبيهات، النماذج. \n
- Push — يعمل فقط داخل UINavigationController. يتم "دفع" المتحكم إلى المكدس، ويظهر من اليمين (افتراضيًا) ويحصل تلقائيًا على زر "رجوع". مثالي للشاشات الهرمية: قائمة -> تفاصيل. \n
للاستخدام push، استخدم الطريقة navigationController?.pushViewController(_:animated:).
// Push (يتطلب UINavigationController)\nif let navigationController = navigationController {\n navigationController.pushViewController(detailVC, animated: true)\n} else {\n present(detailVC, animated: true, completion: nil) // fallback\n}\n\n3. نقل البيانات قبل Present
\n\nأحد أكثر الأسئلة شيوعًا: "كيف أنقل البيانات إلى ViewController الجديد قبل ظهوره؟". الإجابة بسيطة: استخدم الخصائص أو الطرق الخاصة بالمتحكم قبل استدعاء present.
\n\nمثال مع نقل نص
\nلنفترض أن في DetailViewController خاصية:
\n\nclass DetailViewController: UIViewController {\n var receivedMessage: String = ""\n \n ov