UIPercentDrivenInteractiveTransition完成后会产生无关的动画 [英] UIPercentDrivenInteractiveTransition yielding extraneous animation when done

查看:608
本文介绍了UIPercentDrivenInteractiveTransition完成后会产生无关的动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有 UIPercentDrivenInteractiveTransition 的交互式自定义推送转换。手势识别器成功调用交互控制器的 updateInteractiveTransition 。同样,当我调用交互控制器的 finishInteractiveTransition 时,动画成功完成。

I'm using an interactive custom push transition with a UIPercentDrivenInteractiveTransition. The gesture recognizer successfully calls the interaction controller's updateInteractiveTransition. Likewise, the animation successfully completes when I call the interaction controller's finishInteractiveTransition.

但是,有时候我会在结尾处获得额外的一些分散注意力的动画(它似乎重复了动画的后半部分)。使用相当简单的动画,我很少在iPhone 5上看到这种症状(虽然我在慢速笔记本电脑上工作时经常在模拟器上看到它)。如果我使动画的计算成本更高(例如大量阴影,多个视图设置不同方向的动画等),则设备上此问题的频率会增加。

But, sometimes I get a extra bit of distracting animation at the end (where it seems to repeat the latter part of the animation). With reasonably simple animations, I rarely see this symptom on the iPhone 5 (though I routinely see it on the simulator when working on slow laptop). If I make the animation more computationally expensive (e.g. lots of shadows, multiple views animating different directions, etc.), the frequency of this problem on the device increases.

其他人都看到了这个问题并想出了一个解决方案,而不是简化动画(我承认应该做的事情)和/或编写我自己的交互控制器? UIPercentDrivenInteractiveTransition 方法具有一定的优雅性,但我对它不确定地行为不端的事实感到不安。有其他人看过这种行为吗?有没有人知道其他解决方案?

Has anyone else seen this problem and figured out a solution other than streamlining the animations (which I admittedly should do anyway) and/or writing my own interaction controllers? The UIPercentDrivenInteractiveTransition approach has a certain elegance to it, but I'm uneasy with the fact that it misbehaves non-deterministically. Have others seen this behavior? Does anyone know of other solutions?

为了说明效果,请参见下图。注意第二个场景,红色视图,当动画结束时,似乎第二次重复动画的后半部分。

To illustrate the effect, see the image below. Notice how the second scene, the red view, when the animation finishes, seems to repeat the latter part of its animation a second time.

此动画由以下内容生成:

This animation is generated by:


  • 重复调用 updateInteractiveTransition ,将更新从0%提升到40%;

  • repeatedly calling updateInteractiveTransition, progressing update from 0% to 40%;

暂时暂停(因此您可以区分交互式转换和由 finishInteractiveTransition 产生的完成动画);

momentarily pausing (so you can differentiate between the interactive transition and the completion animation resulting from finishInteractiveTransition);

然后调用 finishInteractiveTransition 来完成动画;和

then calling finishInteractiveTransition to complete the animation; and

动画控制器动画的完成块调用 completeTransition 用于 transitionContext ,以便清理所有内容。

the animation controller's animation's completion block calls completeTransition for the transitionContext, in order to clean everything up.

进行一些诊断,似乎是最后一步触发了无关的动画。动画完成时会调用动画控制器的完成块,但是一旦我调用 completeTransition ,它有时会重复动画的最后一位(特别是在使用复杂的动画时) 。

Doing some diagnostics, it appears that it is this last step that triggers that extraneous bit of animation. The animation controller's completion block is called when the animation is finished, but as soon as I call completeTransition, it sometimes repeats the last bit of the animation (notably when using complex animations).

我不认为这是相关的,但这是我配置导航控制器以执行交互式过渡的代码:

I don't think it's relevant, but this is my code for configuring the navigation controller to perform interactive transitions:

- (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 的结果。

Note, when I put logging statement where I call completeTransition, I can see that this extraneous bit of animation happens after I call completeTransition (even though the animation was really done at that point). This would suggest that that extra animation may have been a result of the call to completeTransition.

仅供参考我是的,我用手势识别器完成了这个实验:

FYI, I've done this experiment with a gesture recognizer:

- (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 (从等式中删除手势识别器),它仍然表现出这种奇怪的行为:

I also did it by calling the updateInteractiveTransition and finishInteractiveTransition manually (eliminating the gesture recognizer from the equation), and it still exhibits this strange behavior:

[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隔离的问题复杂的动画。我可以通过简化问题来最小化问题(例如,快照和动画快照视图)。我还怀疑我可以通过不使用 UIPercentDrivenInteractiveTransition 并编写我自己的交互控制器来解决这个问题,它可以自己动画,而无需插入 animationWithDuration 阻止。

Bottom line, I've concluded that this is a problem isolated to UIPercentDrivenInteractiveTransition with complex animations. I can minimize the problem by simplifying them (e.g. snapshotting and animated snapshotted views). I also suspect I could solve this by not using UIPercentDrivenInteractiveTransition and writing my own interaction controller, which would do the animation itself, without trying to interpolate the animationWithDuration block.

但我想知道是否有人已经想出使用复杂动画的 UIPercentDrivenInteractiveTransition 的任何其他技巧。

But I was wondering if anyone has figured out any other tricks to using UIPercentDrivenInteractiveTransition with complex animations.

推荐答案

我见过类似的东西。我有两种可能的解决方法。一种是在动画完成处理程序中使用延迟性能:

I've seen something similar. I have two possible workarounds. One is to use delayed performance in the animation completion handler:

} 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;
}];

另一种可能性是:不要使用百分比驱动动画!在手动驱动交互式自定义动画我自己时,我永远不会出现这样的问题。

The other possibility is: don't use percent-drive animation! I've never had a problem like this when driving the interactive custom animation myself manually.

这篇关于UIPercentDrivenInteractiveTransition完成后会产生无关的动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆