UIPercentDrivenInteractiveTransition الغلة دخيلة الرسوم المتحركة عند القيام به

StackOverflow https://stackoverflow.com//questions/23047350

  •  21-12-2019
  •  | 
  •  

سؤال

أنا باستخدام تفاعلية مخصصة دفع عملية الانتقال UIPercentDrivenInteractiveTransition.لفتة التعرف بنجاح المكالمات التفاعل تحكم updateInteractiveTransition.وبالمثل ، فإن الرسوم المتحركة بنجاح عندما اتصل التفاعل تحكم finishInteractiveTransition.

ولكن في بعض الأحيان لا تحصل على بت إضافية من تشتيت الرسوم المتحركة في نهاية (حيث يبدو أن تكرار الجزء الأخير من الرسوم المتحركة).مع بسيطة معقولة الرسوم المتحركة, أنا نادرا ما نرى هذه الأعراض على اي فون 5 (على الرغم من أنني بشكل روتيني نرى ذلك على محاكاة عند العمل على بطء الكمبيوتر المحمول).إذا كنت جعل الرسوم المتحركة أكثر مكلفة حسابيا (مثلا ، الكثير من الظلال ، وجهات نظر متعددة موحية اتجاهات مختلفة ، الخ) ، تردد هذه المشكلة على جهاز الزيادات.

وقد أي شخص آخر ينظر إلى هذه المشكلة و اكتشفت الحل بخلاف تبسيط الرسوم المتحركة (التي أنا المسلم ينبغي القيام به على أي حال) و/أو كتابة بلدي التفاعل تحكم ؟ على UIPercentDrivenInteractiveTransition نهج معين الأناقة ، لكنني قلق من حقيقة أنه يسيء التصرف غير deterministically.آخرون رأيت هذا السلوك ؟ لا أحد يعرف من غيرها من حلول ؟

لتوضيح تأثير ، انظر الصورة أدناه.لاحظ كيف المشهد الثاني الحمراء نظر ، عندما المتحركة التشطيبات ، ويبدو أن تكرار الجزء الأخير من الرسوم المتحركة للمرة الثانية.

animation not right

هذه الرسوم المتحركة التي تم إنشاؤها بواسطة:

  • يدعو مرارا وتكرارا 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.عرض" تم تعيين مرتين ، مما يجعل الرسوم المتحركة لديهم سلوك غير مرغوب فيه

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top