顺利更新正在运行的动画

时间:2013-05-28 08:52:36

标签: ios uiviewanimation

我有很多图像我运行连续动画。如何平滑地更新这些运行的动画,以便它们之间没有可见的过渡,除非是动画的一部分。

e.g。旋转和缩放图像,然后更新动画以按原样旋转,但稍微放大。我目前看到了明显的变化。

我可以想象,缩放应该在动画块中完成,它们只是像以前一样运行旋转动画,然后问题就是旋转会在它放大时停止。

我需要它是无缝的。例如即使使用UIViewAnimationOptionBeginFromCurrentState

,此代码块也不会导致平滑缩放
[UIView animateWithDuration:0.5
                      delay:0
                    options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseOut //| UIViewAnimationOptionRepeat
                 animations:(void (^)(void)) ^{
                     imageViewToScale.transform = CGAffineTransformMakeScale(1.2, 1.2);
                 }
                 completion:^(BOOL finished){
                     //imageViewToScale.transform=CGAffineTransformIdentity;
                 }];

1 个答案:

答案 0 :(得分:2)

老实说,如果你的视图会持续动画会在运行时改变状态,那么UIView动画不是他最好的方法,可能会导致抖动,而完成处理程序会一遍又一遍地调用。

但是你想在块中做2个动画,你可以在同一个块中设置比例和旋转,它们会同时发生。或者你可以调用一个启动块的函数,并在完成后再次调用它以查看该视图是否有任何新的动画。当没有时,完成块只是停止,有点递归使用它们,虽然这不是我不建议的方法,如果你在很多视图上连续做很多动画。

在OpenGLES中,您可以使用NSTimer运行连续动画,以处理应用中所有动画的更新。如果你走这条路线需要付出更多的努力,你需要自己实现平滑动画的缓动/二次曲线函数。但是,如果扩展clases,则可以为每个图像设置状态,然后当计时器触发时,您可以根据您给出的状态更新其转换。因此,当它旋转一定量的度/弧度时,您可以将其设置为缩放。现在为了保持动画的流畅,您需要使用NSTimerIntervals来确保将经过的时间移动的距离乘以获得平滑的动画。就个人而言,这是我用于可能在屏幕上不断移动的东西的路线,但如果您只需要移动两次然后完成,可能会过度杀死。

编辑:你问的第二步的代码!

因此,您需要声明一个NSTimer,它将轮询您的动画步骤和NSTimeInterval,以便您每步只更新动画的时间。

NSTimer *animationTimer;
NSTimeInterval animationInterval;
NSTimeInterval lastUpdateTime;
float currentRotation;
float current scale;

第三,您需要设置NSTimer来启动视图更新:

- (void)startAnimation
{
    animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView:) userInfo:nil repeats:YES];
}

- (void)stopAnimation
{    
    [animationTimer invalidate];
    animationTimer = nil;
}

然后你需要在你的观点开始时或当你想要开始像这样的东西开始时把它踢掉

- (void)setAnimationInterval:(NSTimeInterval)interval
{
    animationInterval = interval;

    if(animationTimer)
    { 
        [self stopAnimation];
        [self startAnimation];
    } 
} 

然后在drawView:Method中,您需要根据计时器每次触发之间经过的时间更新变换,以便动画平滑且随时间不变。在这一点上基本上是一个线性变换。

- (void)drawView:(id)sender
{
    if(lastUpdateTime == -1)
    {
        lastUpdateTime = [NSDate timeIntervalSinceReferenceDate];
    }

    NSTimeInterval timeSinceLastUpdate = [NSDate timeIntervalSinceReferenceDate] - lastUpdateTime;

    currentRotation = someArbitrarySCALEValue * timeSinceLastUpdate;
    currentScale = someArbitraryROTATIONValue * timeSinceLastUpdate;

    CGAffineTransform scaleTrans =  CGAffineTransformMakeScale(currentScale,currentScale);
    CGAffineTransform rotateTrans =  CGAffineTransformMakeRotation(currentRotation * M_PI / 180);

    imageViewToScale.transform = CGAffineTransformConcat(scaleTrans, rotateTrans);


    lastUpdateTime = [NSDate timeIntervalSinceReferenceDate];
}

请注意,这不会为您的动画添加缓动,也不会在物理上停止您需要使用它。此外,您可能需要确保当旋转超过360时,将其重置为0并分别在度和弧度之间进行转换。

考虑使用物理学来反弹和摩擦,以使事情变得缓慢。

查看二次图,以便使事物随时间平滑移动,基本上是二次插值。

相关问题