2012-09-25 50 views
3

Im尝试将红色方块从视图顶部移动到视图底部的随机位置,并在随机位置再次返回顶部。 该应用程序使用以下代码开始到[超级viewLoad]:IOS动画不能与我的动画块一起工作

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

(与红色正方形视图组50×50,这与开始在左上角的redsquare的应用程序)。

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

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

} 

回答

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) { 


    }]; 
    }]; 
+0

感谢您的建议 - 我喜欢从sheraza的建议,因为它似乎是最合理的给我。我在上面的代码中添加了一个定时器,红色方块现在可以按照预期进行动画了。 – pete

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

使用块的要点是避免使用回调。 – Abizern

+0

避免回调的主要原因是什么?在我看来,块表示法与较早的“beginanimations”表示法相比,一个优点是你可以避免使用选择器,因为选择器没有被编译器验证。 –

+0

因为它将发生事件的逻辑与发起它的代码分开。因此,它不那么有凝聚力的夹头和更多的bug。另外还有一种隐式契约,即一种方法在某种程度上是通用的,可重用的,而且在这些情况下通常不是。 – EricLeaf

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

} 
+0

然而,像这样的嵌套可能会变得非常混乱,如果在稍后的第二个动画完成后他需要创建另一个动画。 –

+0

编辑后更好=) –