Layoutsubviews أثناء الرسوم المتحركة؟
-
02-10-2019 - |
سؤال
انا املك UIView
مع مجموعة من المشاهدات الفرعية ، جميعها في وضعها باستخدام layoutSubviews
. عندما view
يتم تغيير حجمه ، والمواقف النسبية كلها تتغير. أرغب في حدوث إعادة الحساب هذه أثناء تغيير حجم الرسوم المتحركة (باستخدام +[UIView beginAnimations:]
المكالمات). هذا لا يبدو أنه يحدث. أيه أفكار؟
المحلول
الافتراض: تريد أن يكون لديك خطوات رسوم متحركة متعددة (أي موضع لا يتغير خطيًا بحجم الإطار).
هذا غير ممكن مع الرسوم المتحركة "القياسية" "القياسية". لماذا ا؟ يتم تعيين الإطار/الحدود مرة واحدة فقط.
الرسوم المتحركة الأساسية لديه ثلاث "أشجار طبقة":
- ال شجرة النموذج هو المكان الذي يعتقد تطبيقك أن الأمور.
- ال شجرة العرض ما يقرب من ما يتم عرضه على الشاشة.
- ال عرض شجرة هو ما يقرب من ما هي الرسوم المتحركة الأساسية التي تنشئها.
Uiview هو غلاف (رفيع إلى حد ما) حول طبقة النموذج. أثناء الرسوم المتحركة UIVIEW ، تقوم الرسوم المتحركة الأساسية بتحديث الشجرة/التجسيد - تمثل شجرة النموذج نقطة نهاية الرسوم المتحركة. النتيجة هي أن التعليمات البرمجية الخاصة بك يمكن (في معظمها) التعامل مع الرسوم المتحركة على أنها فورية - نقل طريقة عرض من A إلى B تنقلها على الفور إلى B ؛ التغيير يحدث فقط ليكون متحرك للمستخدم.
هناك أشياء أكثر تعقيدًا يمكنك القيام بها مع Calayer/Caanimation مباشرة ، لكنني لم أحقق في هذا الأمر كثيرًا.
يمكنك سلسلة الرسوم المتحركة المتعددة معًا باستخدام -[Uiview SetAnimationDidStopSelector:]. (يمكنك أيضًا محاولة استخدام رسوم متحركة متعددة مع SetAnimationDelay: لكنني لست متأكدًا مما يحدث مع رسوم متحركة متعددة على نفس الخاصية ؛ قد تكون محظوظًا مع setAnimationBeginsFromCurrentState :.)
إذا كنت تريد تحكمًا جيدًا حقًا ، فإن CadisplayLink (OS 3.1+) هو مؤقت يطلق النار بعد تحديث كل الشاشة. خيار الاحتياط (للحصول على 3.0 دعم) هو استخدام nstimer في 30/60 هرتز أو نحو ذلك.
نصائح أخرى
إكمال @Grizzlynetch ، يمكنك تعيين ملف UIViewAnimationOptionLayoutSubviews
خيار الرسوم المتحركة ، لذلك لا تحتاج إلى الاتصال layoutIfNeeded
:
-(void)someMethod{
double duration = ...;
[UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
self.frame = ...;
} completion:nil];
}
أعلم أن هذا سؤال قديم ، لكن هذا الرمز يعمل لي جيدًا (مناسبًا لمثالك على تغيير الإطار).
-(void)layoutSubviews{
[super layoutSubviews];
// layout your subviews here, or whatever
}
-(void)someMethod{
double duration=...;
[UIView animateWithDuration:duration animations:^{
self.frame = ...;
[self layoutIfNeeded];
}];
}
بالطبع يمكنك استدعاء هذه الطريقة من كائن آخر. تتمثل "الخدعة" في استدعاء Layoutifneed (أو LayoutSubviews مباشرة - نفس الشيء ، إذا قمت بتغيير الإطار الذي يسمى setNeedSlayout).
كما TC. شرح بشكل جيد "أشجار الطبقة" ، فأنت فقط تجبر طبقة العرض على عرض المرحلة النهائية من طبقة النموذج مع الرسوم المتحركة.
تتمثل ميزة هذه الطريقة في إمكانية التحكم عندما يكون تغيير الإطار/الحدود متحركة وعندما تكون فورية.
أمل أن هذا يساعد شخصاما:).
النشر للاكتمال. بفضل TC. لشرح أن ما أريد القيام به ، بالضبط ، لا يدعمه الرسوم المتحركة الأساسية.
توصلت في النهاية بحل معقول. بدلاً من ذلك ، قم بتخطيط وجهاتي الفرعية في llayoutsubviews ، أقوم بذلك في -setBounds :. بعد ذلك ، عندما ألفت -metsbounds: اتصل في uiview +stheranimations: block ، هذه المكالمات الموضحة هي أيضًا متحركة ، والنتيجة النهائية هي كل شيء يتم تحريكه بشكل صحيح إلى حيث يجب أن يكون الله.