سلسلة مستجيب دائرة الرقابة الداخلية أو ما يطلبونه في المقابلة

صورة


ما هو الفرق بين المثال الأول والثاني؟

ما هو الهدف المسؤول عن؟

في هذه الحالة يتم استدعاء الأسلوب عند النقر فوق الزر؟

TL ؛ د


عند النقر فوق زر ، يتم استدعاء الأسلوب لدينا في كلتا الحالتين.


في المثال الأول فقط ، سيحاول UIKit استدعاء الطريقة في الهدف المحدد (لدينا ViewController ). سوف تتعطل إذا كانت هذه الطريقة غير موجودة.


في المثال الثاني ، يتم استخدام سلسلة مستجيب iOS ، UIKit عن أقرب UIResponder a الذي لديه هذه الطريقة. لن يكون هناك أي تعطل إذا لم يتم العثور على طريقة لدينا.


UIViewController, UIView, UIApplication UIResponder ترث من UIResponder .


سلسلة مستجيب دائرة الرقابة الداخلية وما تحت الغطاء


تتم معالجة عملية سلسلة iOS Responder UIKit بواسطة UIKit ، والتي تعمل ديناميكيًا مع قائمة مرتبطة من UIResponder . UIKit إنشاء قائمة UIKit هذه من المستجيب الأول (أول UIResponder الذي سجل الحدث ، لدينا UIButton(UIView) subviews .


صورة


UIKit يذهب من خلال قائمة UIResponder ويتحقق مع canPerformAction .


 open func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool 

إذا كان لا يمكن أن تعمل UIResponder المحدد مع طريقة محددة ،
يرسل UIKit الإجراءات بشكل متكرر إلى UIResponder التالي في القائمة باستخدام الطريقة target التي تُرجع UIResponder التالي.


 open func target(forAction action: Selector, withSender sender: Any?) -> Any? 

تتكرر هذه العملية حتى UIResponder أحد UIResponder العمل مع طريقتنا أو تنتهي القائمة ويتجاهل النظام هذا الحدث.


في المثال الثاني للنقر ، تمت معالجته بواسطة UIKit ، ولكن أرسل UIKit أولاً طلبًا إلى UIView لأنه كان المستجيب الأول. لم يكن لديه الطريقة المطلوبة ، لذلك قام UIKit بإعادة توجيه الإجراءات إلى UIResponder التالي في قائمة مرتبطة كانت UIViewController لها الطريقة المطلوبة.


في معظم الحالات ، iOS Responder Chain هي قائمة subviews بسيطة من subviews ، لكن يمكن تغيير ترتيبها. يمكنك جعل UIResponder (becomeFirstResponder) أصبح UIResponder (becomeFirstResponder) تصبح
UIResponder الأول وإعادته إلى الموضع القديم باستخدام resignFirstResponder . يستخدم هذا غالبًا مع UITextField لإظهار لوحة المفاتيح التي سيتم استدعاؤها فقط عندما يكون UITextField هو first responder .


دائرة الرقابة الداخلية المستجيب سلسلة و UIEvent


وتشارك سلسلة المستجيب أيضا في لمس الشاشة ، والحركات ، والنقرات. عندما يكتشف النظام نوعًا من الأحداث (اللمس ، الحركة ، التحكم عن بعد ، اضغط) ، يتم إنشاء UIEvent تحت الغطاء ويتم إرساله باستخدام طريقة UIWindow UIApplication.shared.sendEvent() إلى UIWindow . بعد تلقي الحدث ، تحدد UIWindow استخدام hitTest:withEvent التي ينتمي إليها UIResponder هذا الحدث UIResponder first responder . التالي هو العمل مع قائمة مرتبطة بـ UIResponder الموضحة أعلاه.


للعمل مع UIEvent للنظام ، يمكن UIEvent الفرعية من UIResponder (UIViewController, UIView, UIApplication) تجاوز هذه الأساليب:


 open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) open func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) open func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) open func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) open func pressesChanged(_ presses: Set<UIPress>, with event: UIPressesEvent?) open func pressesEnded(_ presses: Set<UIPress>, with event: UIPressesEvent?) open func pressesCancelled(_ presses: Set<UIPress>, with event: UIPressesEvent?) open func motionBegan(_ motion: UIEvent.EventSubtype, with event: UIEvent?) open func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?) open func motionCancelled(_ motion: UIEvent.EventSubtype, with event: UIEvent?) open func remoteControlReceived(with event: UIEvent?) 

على الرغم من أن القدرة على وراثة و sendEvent يدوياً موجودة ، UIResponder مخصص لهذا الغرض. يمكن أن يؤدي ذلك إلى إنشاء العديد من المشكلات مع تشغيل الأحداث المخصصة ، والتي يمكن أن تؤدي إلى إجراءات غير مفهومة تسببها first responeder العشوائي الذي يمكنه الاستجابة لهذا الحدث.


لماذا هو مفيد ، حيث للاستخدام


على الرغم من حقيقة أن iOS Responder Chain التحكم فيها بالكامل بواسطة UIKit ، إلا أنه يمكن استخدامها لحل مشكلة التفويض / التواصل. UIResponder إجراءات UIResponder NotificationCenter.default.post لمرة واحدة.


دعنا نأخذ مثالا ، لدينا UIViewController ، وهو عميق في مكدس UINavigationController ونحن بحاجة إلى إخباره بما حدث عندما تم النقر على زر على شاشة أخرى. يمكنك استخدام نقش delagate أو NotificationCenter.default.post ، ولكن الخيار البسيط إلى حد ما هو استخدام iOS Responder Chain .


 button.addTarget(nil, action: #selector(RootVC.doSomething), for: .touchUpInside) 

عند الضغط عليه ، سيتم استدعاء الطريقة الموجودة في UIViewController . #selector يمكن أن تأخذ المعلمات التالية:


 @objc func doSomething() @objc func doSomething(sender: Any?) @objc func doSomething(sender: Any?, event: UIEvent?) 

المرسل هو الكائن الذي أرسل الحدث - UIButton و UITextField وما إلى ذلك.


موارد إضافية للتعلم [eng]:


وصف جيد لـ UIEvent و UIResponder واثنين من الأمثلة المتقدمة (منسق النداء)
اقرأ المزيد عن سلسلة استجابة دائرة الرقابة الداخلية
مثال سلسلة المستجيب في الممارسة العملية
قبالة قفص الاتهام على سلسلة دائرة الرقابة الداخلية المستجيب
قبالة قفص الاتهام من قبل UIResponder

Source: https://habr.com/ru/post/ar464463/


All Articles