تحريك العرض مع لوحة المفاتيح باستخدام Swift: التحسين والأداء
\n\nكل مطور iOS واجه مرة واحدة على الأقل موقفًا حيث تغطي لوحة المفاتيح بوقاحة UITextField أو UITextView. المستخدم ينقر على الحقل، تظهر لوحة المفاتيح، لكن الواجهة تبقى غير مبالية. النتيجة: إحباط، أخطاء في الإدخال، وحذف التطبيق. حل هذه المشكلة في Swift ليس مجرد "تحريك العرض مع لوحة المفاتيح"، بل هو علم كامل عن الأداء وتجربة المستخدم.
في هذه المقالة، سنشرح كيفية تنفيذ تحريك العرض مع لوحة المفاتيح باستخدام Swift بشكل صحيح، تحسين الرسوم المتحركة، وتجنب الأخطاء الشائعة. ستحصل على كود جاهز يمكنك إدراجه مباشرة في مشروعك، وستفهم لماذا بعض الأساليب تبطئ واجهة المستخدم بينما تعمل أخرى بشكل مثالي.
\n\nلماذا تعمل الحلول القياسية بشكل سيء غالبًا؟
\n\nعلى Stack Overflow، سؤال "تحريك العرض مع لوحة المفاتيح باستخدام Swift" حصل على آلاف المشاهدات. وهذا ليس من قبيل الصدفة. العديد من المبتدئين ينسخون أول حل يصادفونه من عام 2015، والذي يستخدم UIKeyboardWillShowNotification ويغير إطار UIView بشكل صارم. النتيجة: رسوم متحركة متقطعة، تسرب للذاكرة، وأخطاء على موديلات iPhone المختلفة.
المشاكل الرئيسية للأساليب القديمة:
\n- \n
- تغيير
frameمباشرة دون مراعاةsafe area; \n - تجاهل مدة ومنحنيات الرسوم المتحركة للوحة المفاتيح; \n
- عدم معالجة تدوير الشاشة وتعدد المهام; \n
- النسيان: لا يتم إزالة الإشعارات، ولا يتم تنظيف الكائنات. \n
Swift الحديث (5.0+) و UIKit يسمحان بفعل كل شيء بأناقة وسرعة. دعنا نستعرض النمط الأمثل.
\n\nالتحضير: ما سنحتاجه
\n\nلتنفيذ تحريك العرض مع لوحة المفاتيح باستخدام Swift سنستخدم:
\n- \n
NotificationCenterلتتبع أحداث لوحة المفاتيح; \n UIView.animateمع معلمات من الإشعار; \n UIScrollViewكحاوية أساسية (لكن يمكن الاستغناء عنها); \n - إدارة صحيحة للذاكرة (weak self, removeObserver). \n
سنكتب كل الكود في UIViewController. إذا كنت تستخدم SwiftUI — المبادئ نفسها، لكن API مختلف (حول ذلك في نهاية المقالة).
الخطوة 1: تسجيل إشعارات لوحة المفاتيح
\n\nأول ما يجب فعله هو الاشتراك في إشعارين رئيسيين: UIResponder.keyboardWillShowNotification و UIResponder.keyboardWillHideNotification. هما اللذان يعطياننا الحجم والمدة ومنحنى الرسوم المتحركة.
override func viewDidLoad() {\n super.viewDidLoad()\n \n NotificationCenter.default.addObserver(\n self,\n selector: #selector(keyboardWillShow),\n name: UIResponder.keyboardWillShowNotification,\n object: nil\n )\n \n NotificationCenter.default.addObserver(\n self,\n selector: #selector(keyboardWillHide),\n name: UIResponder.keyboardWillHideNotification,\n object: nil\n )\n}\n\n\nلاحظ: object: nil يعني أننا نستمع لإشعارات من أي لوحة مفاتيح. هذا صحيح لمعظم الحالات.
الخطوة 2: معالج keyboardWillShow
\n\nفي هذه الدالة، نستخرج من الإشعار حجم لوحة المفاتيح ومدة الرسوم المتحركة. ثم نحرك العرض لأعلى بارتفاع لوحة المفاتيح.
\n\n@objc private func keyboardWillShow(_ notification: Notification) {\n guard let userInfo = notification.userInfo,\n let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,\n let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double,\n let curve = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? UInt else {\n return\n }\n \n let keyboardHeight = keyboardFrame.height\n let animation