0

我正在使用块在同一个 UIImageView 上制作两个动画。动画不是完全背靠背,而是几乎;两者之间有一些逻辑。

  • 将 UIImageView 从视图上的一个位置动画到另一个位置。
  • 执行确定是否允许图像留在那里的逻辑
  • 如果不允许,撤消动画(UIImageView 弹回原始位置)

如果我按上述方式实现,则仅显示第二个动画(据我了解,这是正常行为)。如果我将逻辑和第二个动画块嵌套在第一个的完成块中,我会看到两个动画,但是有相当多的代码会塞进那个完成块,而且看起来很丑陋而且不合适。

在非嵌套配置中,为什么iOS要缩短前面的动画,只执行最后一个,我怎么能强制它等待第一个,然后再执行下一个?我认为它不需要阻塞主线程或在完成块中“坐下来旋转”;我只想显示所有动画。尝试为第二个动画添加延迟无济于事。

这是 CAKeyframeAnimation 的工作吗?

// first animation

[UIView animateWithDuration:0.5
                      delay:0.0
                    options: UIViewAnimationCurveLinear
                 animations:^{movingColor.center = newCenter;
                     movingColor.transform = scaleTransform;}
                 completion:^(BOOL finished){ NSLog(@"forward animation done");}];

if (/* ...color is allowed at that location */) {

    // do some stuff

} else {

    // undo the animation

    [UIView animateWithDuration:0.5
                          delay:0.0
                        options: UIViewAnimationCurveLinear
                     animations:^{movingColor.center = origCenter;
                         movingColor.transform = scaleTransform;}
                     completion:^(BOOL finished){ NSLog(@"back animation done");}];
}
4

3 回答 3

1

正确的做法是如你所说,在第一个的完成中设置第二个,这是正确的方法,

您还可以在另一个开始时添加延迟,这可能会或可能不会起作用,这取决于很多变量

您的第二个动画会有 0.5 的延迟(第一个动画完成的时间)

[UIView animateWithDuration:0.5
                      delay:0.5
                    options: UIViewAnimationCurveLinear
                 animations:^{movingColor.center = origCenter;
                     movingColor.transform = scaleTransform;}
                 completion:^(BOOL finished){ NSLog(@"back animation done");}];
于 2012-06-17T14:35:05.570 回答
1

animateWithDuration异步执行,并立即返回。也就是不等动画结束就执行下一行代码。completion如果您希望在动画完成后执行代码,您可以将代码放入块中,或者您接受第二个动画立即开始(从而取消第一个动画)。

如果您想通过启动动画而不是完成动画来向用户表明有问题,您可以延迟执行第二个动画。UIViewAnimationOptionBeginFromCurrentState如果您延迟第二个动画的持续时间小于第一个动画的持续时间,请记住还要设置该选项:

[UIView animateWithDuration:0.5 
                      delay:0.25 //or some number
                    options: (UIViewAnimationCurveLinear | UIViewAnimationOptionBeginFromCurrentState)
                 animations:^{movingColor.center = origCenter;
                     movingColor.transform = scaleTransform;}
                 completion:^(BOOL finished){ NSLog(@"back animation done");}];
于 2012-06-17T14:44:01.857 回答
1

第二个动画应该在第一个的完成块内有条件地完成。将其放入函数中将使其更具可读性。

- (void)moveColor:(UIView *)view to:(CGPoint)center delay:(NSTimeInterval)delay completion:(void (^)(BOOL finished))complete {

    [UIView animateWithDuration:0.5 delay:delay options:UIViewAnimationCurveLinear animations:^{
        view.center = center;
        view.transform = scaleTransform;  // probably don't need this
    } completion:completion];
}

这样您的逻辑可以与动画代码分开

- (void)someMethod {

    [self moveColor:movingColor to:newCenter delay:0.0 completion:^(BOOL finished) {
        if (/*it can stay*/) {
            // stuff
        } else {
            [self moveColor:movingColor to:origCenter delay:2.0 completion:^(BOOL finished) {}];
        }
    }];
}
于 2012-06-17T14:44:09.183 回答