iphone开发:如何使用NSTimer创建动画

时间:2012-08-27 09:48:54

标签: iphone objective-c ios animation nstimer

在我的应用中,我在viewWillAppear中有这段代码。它只是将随机对象从屏幕顶部动画到底部。问题是我需要检测碰撞,到目前为止我学到的是不可能随时检索动画的坐标。那么如何使用NSTimer实现它呢?或者我应该使用NSTimer?我无法理解。任何线索都将受到赞赏。

-(void)viewWillAppear:(BOOL)animated
{
    for (int i = 0; i < 100; i++) {

        p = arc4random_uniform(320)%4+1;

        CGRect startFrame = CGRectMake(p*50, -50, 50, 50);
        CGRect endFrame   = CGRectMake(p*50, CGRectGetHeight(self.view.bounds) + 50,
                                       50,
                                       50);

        animatedView = [[UIView alloc] initWithFrame:startFrame];
        animatedView.backgroundColor = [UIColor redColor];

        [self.view addSubview:animatedView];

        [UIView animateWithDuration:2.f
                              delay:i * 0.5f
                            options:UIViewAnimationCurveLinear
                         animations:^{
                             animatedView.frame = endFrame;
                         } completion:^(BOOL finished) {
                             [animatedView removeFromSuperview];
                         }];

}

4 个答案:

答案 0 :(得分:3)

我会放弃NSTimer CADisplayLink向您的目标发送消息。 NSTimer可能会导致口吃动画,因为它不会与设备的屏幕刷新率同步。 CADisplayLink正是如此,让你的动画像黄油一样运行。

文档: http://developer.apple.com/library/ios/#documentation/QuartzCore/Reference/CADisplayLink_ClassRef/Reference/Reference.html

最终,使用CADisplayLink看起来像这样:

- (id) init {
    // ...
    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(update:)];
    [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    // ...
}

- (void) update {
    [myView updatePositionOrSomethingElse];
}

答案 1 :(得分:2)

您可以以较小的增量(在循环中)对象进行动画处理。每次完成动画时,都可以获得坐标。

答案 2 :(得分:2)

您的陈述:

  

是否无法随时检索坐标   动画

似乎不正确你检查this

看起来您可以使用CALayer的presentationLayer属性在动画期间提取坐标信息:

CGRect movingFrame = [[yourView.layer presentationLayer] frame];

如果动画期间发生碰撞,我会使用此信息来检查时间。因此,我将使用计时器来检查碰撞状态,而不是为视图设置动画。

答案 3 :(得分:1)

我认为你可以在for循环中使用beginAnimations - commitAnimations语法,例如。直到10,所以在每个周期后你都可以检查碰撞

CGRect incrementedViewFrame;

for(int i = 0; i < 10; ++i)
{

      incrementedViewFrame = CGRectMake(/*calculate the coords here*/);

      if(collision)
      {
           //do stuff
      }
      else
      {
           //do an other animation cycle
          [UIView beginAnimations:nil context:NULL];
          [UIView setAnimationBeginsFromCurrentState:YES];
          [UIView setAnimationDuration:0.1f];
          [[self viewToAnimate]setFrame:incrementedViewFrame];
          [UIView commitAnimations];
      }
}

我希望有所帮助!