3

我试图让一个红色方块从视图顶部移动到视图底部的随机位置,然后在随机位置再次返回顶部。该应用程序从以下代码开始进入[super viewLoad]:

[redSquare setCenter:CGPointMake(25,25)];

(红色方块视图设置为 50 x 50,这将在左上角以红色方块启动应用程序)。

动画的第一部分效果很好 - 红色方块动画到页面底部的随机位置。但是,它会在没有动画的情况下跳到顶部的随机位置。请帮助我做错了什么或任何其他解决方案来帮助这个简单的动画。

 -(void)moving{

    [UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationCurveEaseIn animations:^{
   int randomx = arc4random() % 295;
   [redSquare setCenter:CGPointMake(randomx,435)];


    } completion:^(BOOL finished) {

   [redSquare setCenter:CGPointMake(redSquare.frame.origin.x,25)];
   }];

}
4

3 回答 3

4

您的完成块只是设置新位置。您没有将其动画化回顶部:

试试这个,而不是

-(void)moving {

    [UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationCurveEaseIn animations:^{
        int randomx = arc4random() % 295;
        [redSquare setCenter:CGPointMake(randomx,435)];
    } completion:^(BOOL finished) {
        [UIViewAnimateWithDuration:1.0 delay:0.0 options:UIViewAnimationCurveEaseIn animations:^{
        [redSquare setCenter:CGPointMake(redSquare.frame.origin.x,25)];
        } completion: NULL
    }];

}

编辑添加

确实,子级别会让人感到困惑,但是如果您将块与方法分开定义,则可以使生活变得简单并减少缩进。

例如,您可以将上面的内容重写为:

-(void)moving {

    workBlk_t animationBlock = ^ {
        int randomx = arc4random() % 295;
        [redSquare setCenter:CGPointMake(randomx,435)];
    };

    void (^completionBlock)(BOOL finished) = ^{
        [UIViewAnimateWithDuration:1.0 delay:0.0 options:UIViewAnimationCurveEaseIn animations:^{
            [redSquare setCenter:CGPointMake(redSquare.frame.origin.x,25)];
        } completion : NULL
    };

    [UIView animateWithDuration:1.0 
                          delay:0.0 
                        options:UIViewAnimationCurveEaseIn 
                     animations:animationBlock 
                     completion:completionBlock
    }];

}
于 2012-09-25T07:45:19.717 回答
3

您应该在完成块中启动新动画,例如:

    completion:^(BOOL finished) {
          [UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationCurveEaseIn      animations:^{
          int randomx = arc4random() % 295;
          [redSquare setCenter:CGPointMake(randomx,25)];


    } completion:^(BOOL finished) {


   }];
   }];
于 2012-09-25T07:42:48.677 回答
1

这部分完全符合您的描述:

completion:^(BOOL finished) {
   [redSquare setCenter:CGPointMake(redSquare.frame.origin.x,25)];
}

即动画完成后将对象返回到屏幕顶部。这不会是动画的,它会在动画完成后发生,因此它是即时的。

动画完成后需要触发新的动画。

然而,创建多个嵌套动画块可能会变得有点混乱,最干净的方法是创建另一个动画方法,并在第一个动画完成时调用它,如下所示:

-(void) moveDown{
   [UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationCurveEaseIn animations:^{
       int randomx = arc4random() % 295;
       [redSquare setCenter:CGPointMake(randomx,435)];

   } completion:^(BOOL finished) {
       // First animation completed
       [self moveBack];
   }];
}

-(void) moveBack{
   [UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationCurveEaseIn animations:^{
       [redSquare setCenter:CGPointMake(redSquare.frame.origin.x,25)];
   } completion:^(BOOL finished) {
       // Second animation completed
   }];
}
于 2012-09-25T07:44:12.497 回答