قصة مراقب عرض واحد أراد التباهي بلطف

ذات مرة كان هناك وحدة تحكم عرض متواضعة VCYellow . ولم يكن لديه صورة ، ولا نص ، ولا حتى منطق تجاري صغير. عاش حياة عادية للتحكم في العرض.


قدمه زميله في وحدة التحكم في العرض VCMain أحيانًا إلى العالم:


class VCMain: UIViewController { ... @IBAction func onBtnTapMeTapped(_ sender: Any) { let vcYellow = self.storyboard!.instantiateViewController(withIdentifier: "VCYellow") as! VCYellow self.present(vcYellow, animated: true, completion: nil) } 

و VCYellow بدوره كان مختبئًا بمساعدة زر "X" واحد ، وهو بالمناسبة فخور جدًا بما يلي:


 class VCYellow: UIViewController { ... @IBAction func onBtnCloseTapped(_ sender: Any) { self.dismiss(animated: true, completion: nil) } 

ولم يكن الأمر يبدو سيئًا للغاية ، ولكنه ممل ودنيوي:



لكن كان لبطلنا حلم أن يتعلم كيف يظهر ويختفي في الجمال. نعم ، حتى تتمكن من تغيير هذا الجمال في وقت لاحق في العطلات أو لمجرد مزاج جيد.



مرت سنوات ... وهكذا كان الحلم سيظل حلما لو لم يتعلم VCYellow عن السحر المسمى:


 UIViewControllerTransitioningDelegate 

وتكمن قوة هذا السحر في حقيقة أنه يجعل من الممكن أن تنزلق الرسوم المتحركة المناسبة لإظهار وإخفاء وحدة تحكم العرض. فقط ما حلمت به وحدة التحكم لدينا.
قرأ في مخطوطات قديمة كيفية استخدام التعويذة وبدأ في التحضير.
كتبت سرير مع التعويذة نفسها حتى لا أنسى:


 extension VCYellow: UIViewControllerTransitioningDelegate { func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return AnimatorPresent(startFrame: self.startFrame) } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return AnimatorDismiss(endFrame: self.startFrame) } } 

في ذلك ، رسم بعناية أنه للعرض تحتاج إلى استخدام AnimatorPresent الرسوم المتحركة ، وعند إغلاق AnimatorDismiss .
حسنًا ، كمساعدة لكل من الرسوم المتحركة ، تقرر نقل إطار الزر الرئيسي من VCMain


ثم تم ضبطه عقلياً. لأنه بدون الموقف الصحيح ، كما تعلمون ، لا يوجد سحر يعمل:


 override func viewDidLoad() { super.viewDidLoad() self.modalPresentationStyle = .custom self.transitioningDelegate = self } 

طلب من صديقه VCMain أن يقدم نفسه للتحقق من كيفية عمل السحر و ... لم يعمل بأي شكل من الأشكال ...
اتضح أن AnimatorPresent و AnimatorDismiss لا يظهران بمفردهما.


لقد فات الأوان للتوقف ، وقرر بطلنا إنشاء الرسوم المتحركة اللازمة. لقد بحثت في القسم الضروري من المخطوطات القديمة واكتشفت أن شيئين كافيان لإنشاء الرسوم المتحركة.


أولاً ، تحتاج إلى ضبط الوقت المخصص للرسم المتحرك:


 func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return 0.3 } 

وثانيًا الإشارة إلى الرسوم المتحركة نفسها:


 func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { //1 guard let vcTo = transitionContext.viewController(forKey: .to), let snapshot = vcTo.view.snapshotView(afterScreenUpdates: true) else { return } //2 let vContainer = transitionContext.containerView //3 vcTo.view.isHidden = true vContainer.addSubview(vcTo.view) //4 snapshot.frame = self.startFrame vContainer.addSubview(snapshot) UIView.animate(withDuration: 0.3, animations: { //5 snapshot.frame = (transitionContext.finalFrame(for: vcTo)) }, completion: { success in //6 vcTo.view.isHidden = false snapshot.removeFromSuperview() transitionContext.completeTransition(true) }) } 

  1. اسحب وحدة التحكم في العرض المقدمة (في حالتنا VCYellow) والتقط صورة لها. هناك حاجة إلى صورة لتبسيط الرسوم المتحركة.
  2. احصل على رأي حول السحر الذي سيحدث. دعونا نسميها السياق.
  3. ربط عرض وحدة التحكم النهائية في السياق وإخفائها. إظهار
  4. تقرر بعد انتهاء الرسوم المتحركة.
  5. تحضير صورة للرسوم المتحركة. اختزل إلى الحجم الأولي ورمي السياق.
  6. قم بتقسيم الصورة إلى وضع ملء الشاشة ، وبالتالي تنشيط عملية العرض التقديمي.
  7. بعد الانتهاء من الرسوم المتحركة ، اعرض العرض الحقيقي لوحدة التحكم النهائية ،
  8. تخلص من الصورة وأبلغ عن انتهاء العمل.

ونتيجة لذلك ، كان هناك رسوم متحركة للعرض:


 import UIKit class AnimatorPresent: NSObject, UIViewControllerAnimatedTransitioning { let startFrame: CGRect init(startFrame: CGRect) { self.startFrame = startFrame } func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return 0.3 } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { guard let vcTo = transitionContext.viewController(forKey: .to), let snapshot = vcTo.view.snapshotView(afterScreenUpdates: true) else { return } let vContainer = transitionContext.containerView vcTo.view.isHidden = true vContainer.addSubview(vcTo.view) snapshot.frame = self.startFrame vContainer.addSubview(snapshot) UIView.animate(withDuration: 0.3, animations: { snapshot.frame = (transitionContext.finalFrame(for: vcTo)) }, completion: { success in vcTo.view.isHidden = false snapshot.removeFromSuperview() transitionContext.completeTransition(true) }) } } 

وبعد ذلك لم يكن من الصعب كتابة الرسوم المتحركة للاختباء ، والتي تفعل نفس الشيء ، ولكن العكس بالعكس:


 import UIKit class AnimatorDismiss: NSObject, UIViewControllerAnimatedTransitioning { let endFrame: CGRect init(endFrame: CGRect) { self.endFrame = endFrame } func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return 0.3 } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { guard let vcTo = transitionContext.viewController(forKey: .to), let vcFrom = transitionContext.viewController(forKey: .from), let snapshot = vcFrom.view.snapshotView(afterScreenUpdates: true) else { return } let vContainer = transitionContext.containerView vContainer.addSubview(vcTo.view) vContainer.addSubview(snapshot) vcFrom.view.isHidden = true UIView.animate(withDuration: 0.3, animations: { snapshot.frame = self.endFrame }, completion: { success in transitionContext.completeTransition(true) }) } } 

بعد الانتهاء من جميع اللمسات الأخيرة ، طلب VCYellow مرة أخرى من صديقه VCMain أن يقدم نفسه و lo !



عملت السحر! حلم VCYellow تحقق! الآن يمكنه أن يظهر ويختفي كما يريد ولن يحد شيء من خياله!


يمكن تحميل مشروع مثال هنا.


المقالة التي استخدمتها للإلهام هنا.

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


All Articles