为循环UIView动画块添加随机性

Dre*_*air 3 iphone objective-c ipad uiviewanimation ios

我正在尝试使用animateWithDuration:方法在iOS中制作动画.

我正在屏幕上移动一个图像(UIImageView中的云的简单图片),然后让这个动画在循环中运行,我想在每次穿过屏幕时改变速度(持续时间).

我尝试了几种方法,但两种方式对我来说都不正确.

我首先虽然可以像这样使用UIViewAnimationOptionRepeat:

[UIImageView animateWithDuration:arc4random() % 10 + 1
                           delay:0.0
                         options:UIViewAnimationOptionCurveLinear | UIViewAnimationOptionRepeat
                      animations:^{
 //moving the cloud across the screen here
}
completion:^(BOOL finished) {
    NSLog(@"Done!");
}];
Run Code Online (Sandbox Code Playgroud)

但是这似乎并没有再次调用arc4random()来重置持续时间...即,每次应用程序启动时,云将以随机速度穿过屏幕,而不是每次动画循环时.

然后我尝试使用完成块再次触发动画,如下所示:

-(void)animateMethod
{
[UIImageView animateWithDuration:arc4random() % 10 + 1
                           delay:0.0
                         options:UIViewAnimationOptionCurveLinear
                      animations:^{
 //moving the cloud across the screen here
}
completion:^(BOOL finished) {
    NSLog(@"Done!");
    [self animateMethod];
}];
}
Run Code Online (Sandbox Code Playgroud)

这给了我正在寻找的效果,但当我使用导航控制器推送到另一个视图时,完成块在一个无休止的循环中被触发(我的日志被"Done!"发送垃圾邮件)

任何人都知道如何获得理想的效果我想要正确的方法吗?

Rya*_*los 5

你走在正确的轨道上.关键是你需要只在动画结束时才循环,如果它失败了.所以你需要finished BOOL在告诉它循环之前检查它是否为真.

-(void)animateMethod
{
    [UIImageView animateWithDuration:arc4random() % 10 + 1
                               delay:0.0
                             options:UIViewAnimationOptionCurveLinear
                          animations:^{
     //moving the cloud across the screen here
    }
    completion:^(BOOL finished) {
        if (finished) {
            NSLog(@"Done!");
            [self animateMethod];
        }
    }];
}
Run Code Online (Sandbox Code Playgroud)

这种方法非常适合这种非常简单的动画,当你只做一些时,就像一次可能有3-5个云一样.除此之外,您可能希望使用NSTimer或CADisplayLink设置自己的动画循环并调整其中的云帧.它是一种更加手动的方式,但它甚至可以在UIKit中为您提供一些不错的动画效果.