UIPercentDrivenInteractiveTransition الغلة دخيلة الرسوم المتحركة عند القيام به
-
21-12-2019 - |
سؤال
أنا باستخدام تفاعلية مخصصة دفع عملية الانتقال UIPercentDrivenInteractiveTransition
.لفتة التعرف بنجاح المكالمات التفاعل تحكم updateInteractiveTransition
.وبالمثل ، فإن الرسوم المتحركة بنجاح عندما اتصل التفاعل تحكم finishInteractiveTransition
.
ولكن في بعض الأحيان لا تحصل على بت إضافية من تشتيت الرسوم المتحركة في نهاية (حيث يبدو أن تكرار الجزء الأخير من الرسوم المتحركة).مع بسيطة معقولة الرسوم المتحركة, أنا نادرا ما نرى هذه الأعراض على اي فون 5 (على الرغم من أنني بشكل روتيني نرى ذلك على محاكاة عند العمل على بطء الكمبيوتر المحمول).إذا كنت جعل الرسوم المتحركة أكثر مكلفة حسابيا (مثلا ، الكثير من الظلال ، وجهات نظر متعددة موحية اتجاهات مختلفة ، الخ) ، تردد هذه المشكلة على جهاز الزيادات.
وقد أي شخص آخر ينظر إلى هذه المشكلة و اكتشفت الحل بخلاف تبسيط الرسوم المتحركة (التي أنا المسلم ينبغي القيام به على أي حال) و/أو كتابة بلدي التفاعل تحكم ؟ على UIPercentDrivenInteractiveTransition
نهج معين الأناقة ، لكنني قلق من حقيقة أنه يسيء التصرف غير deterministically.آخرون رأيت هذا السلوك ؟ لا أحد يعرف من غيرها من حلول ؟
لتوضيح تأثير ، انظر الصورة أدناه.لاحظ كيف المشهد الثاني الحمراء نظر ، عندما المتحركة التشطيبات ، ويبدو أن تكرار الجزء الأخير من الرسوم المتحركة للمرة الثانية.
هذه الرسوم المتحركة التي تم إنشاؤها بواسطة:
يدعو مرارا وتكرارا
updateInteractiveTransition
, تتقدم التحديث من 0 ٪ إلى 40 ٪ ،لحظات التوقف (حتى يمكنك التفريق بين التفاعلية الانتقال والانتهاء الرسوم المتحركة الناتجة عن
finishInteractiveTransition
);ثم يدعو
finishInteractiveTransition
لاستكمال الرسوم المتحركة ؛ والرسوم المتحركة تحكم المتحركة
completion
منع المكالماتcompleteTransition
عنtransitionContext
, ، من أجل تنظيف كل شيء.
القيام ببعض التشخيص ، يبدو أن هذا هو الخطوة الأخيرة التي المشغلات التي دخيلة قليلا من الرسوم المتحركة.الرسوم المتحركة تحكم الإنجاز كتلة يسمى عند الرسوم المتحركة النهائي ، ولكن بمجرد أن أسميه completeTransition
, أحيانا يكرر الجزء الأخير من الرسوم المتحركة (لا سيما عند استخدام الرسوم المتحركة المعقدة).
لا اعتقد انها ذات الصلة ، ولكن هذا هو قانون بلدي من أجل تكوين وحدة تحكم الملاحة لأداء التفاعلية التحولات:
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.delegate = self;
self.interationController = [[UIPercentDrivenInteractiveTransition alloc] init];
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController*)fromVC
toViewController:(UIViewController*)toVC
{
if (operation == UINavigationControllerOperationPush)
return [[PushAnimator alloc] init];
return nil;
}
- (id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController*)navigationController
interactionControllerForAnimationController:(id <UIViewControllerAnimatedTransitioning>)animationController
{
return self.interationController;
}
بلدي PushAnimator
هو:
@implementation PushAnimator
- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
return 5.0;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
[[transitionContext containerView] addSubview:toViewController.view];
toViewController.view.frame = CGRectOffset(fromViewController.view.frame, fromViewController.view.frame.size.width, 0);;
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toViewController.view.frame = fromViewController.view.frame;
} completion:^(BOOL finished) {
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
@end
ملاحظة عندما أضع تسجيل البيان حيث أتصل completeTransition
, يمكنني أن أرى أن هذا دخيلة قليلا من الرسوم المتحركة يحدث بعد المكالمة completeTransition
(على الرغم من أن الرسوم المتحركة حقا القيام به في هذه النقطة).هذا يوحي بأن إضافية الرسوم المتحركة قد تم نتيجة الدعوة إلى completeTransition
.
لمعلوماتك, لقد قمت بهذه التجربة مع لفتة التعرف:
- (void)handlePan:(UIScreenEdgePanGestureRecognizer *)gesture
{
CGFloat width = gesture.view.frame.size.width;
if (gesture.state == UIGestureRecognizerStateBegan) {
[self performSegueWithIdentifier:@"pushToSecond" sender:self];
} else if (gesture.state == UIGestureRecognizerStateChanged) {
CGPoint translation = [gesture translationInView:gesture.view];
[self.interactionController updateInteractiveTransition:ABS(translation.x / width)];
} else if (gesture.state == UIGestureRecognizerStateEnded ||
gesture.state == UIGestureRecognizerStateCancelled)
{
CGPoint translation = [gesture translationInView:gesture.view];
CGPoint velocity = [gesture velocityInView:gesture.view];
CGFloat percent = ABS(translation.x + velocity.x * 0.25 / width);
if (percent < 0.5 || gesture.state == UIGestureRecognizerStateCancelled) {
[self.interactionController cancelInteractiveTransition];
} else {
[self.interactionController finishInteractiveTransition];
}
}
}
أنا أيضا فعلت ذلك عن طريق استدعاء updateInteractiveTransition
و finishInteractiveTransition
يدويا (القضاء على هذه اللفتة التعرف من المعادلة) ، وأنه لا يزال يسلك هذا السلوك الغريب:
[self performSegueWithIdentifier:@"pushToSecond" sender:self];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.interactionController updateInteractiveTransition:0.40];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self.interactionController finishInteractiveTransition];
});
});
خلاصة القول لقد خلصت إلى أن هذه هي مشكلة معزولة UIPercentDrivenInteractiveTransition
مع الرسوم المتحركة المعقدة.ما يمكن أن تقلل المشكلة من خلال تبسيط لهم (مثلا ، snapshotting المتحركة snapshotted وجهات النظر).أنا أيضا أظن أن حل هذا عن طريق عدم استخدام UIPercentDrivenInteractiveTransition
والكتابة بلدي التفاعل تحكم ، التي من شأنها أن تفعل الحركة نفسها ، دون محاولة أقحم في animationWithDuration
كتلة.
ولكن أنا أتساءل عما إذا كان أي شخص لديه أحسب أي الحيل باستخدام UIPercentDrivenInteractiveTransition
مع الرسوم المتحركة المعقدة.
المحلول
رأيت شيئا من هذا القبيل.لدي اثنين من الحلول الممكنة.واحد هو استخدام تأخر الأداء في الرسوم المتحركة إكمال معالج:
} completion:^(BOOL finished) {
double delayInSeconds = 0.1;
dispatch_time_t popTime =
dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
BOOL cancelled = [transitionContext transitionWasCancelled];
[transitionContext completeTransition:!cancelled];
});
self.interacting = NO;
}];
إمكانية أخرى هي:لا تستخدم في المئة-محرك الرسوم المتحركة!لقد أبدا مشكلة مثل هذا عند القيادة التفاعلية مخصص الرسوم المتحركة نفسي يدويا.
نصائح أخرى
وتنشأ هذه المشكلة فقط في محاكاة.
الحل:النفس.interactiveAnimator.completionSpeed = 0.999;
علة ذكرت هنا: http://openradar.appspot.com/14675246
والسبب في هذا الخطأ في حال كان وضع إطار عرض يجري الرسوم المتحركة عدة مرات.أنا فقط وضع عرض الإطار مرة واحدة و ثابتة القضايا.
حتى في هذه الحالة ، إطار "toViewController.عرض" تم تعيين مرتين ، مما يجعل الرسوم المتحركة لديهم سلوك غير مرغوب فيه