CABasicAnimation 代替 UIView 动画

Posted

技术标签:

【中文标题】CABasicAnimation 代替 UIView 动画【英文标题】:CABasicAnimation instead of UIView animation 【发布时间】:2014-04-10 09:13:40 【问题描述】:

我有以下动画块,用来做某种选框标签效果。 我有两个标签,我滚动两个,当滚动动画完成时,我设置新帧并再次滚动。动画永远不会停止。

- (void)scrollAwayWithInterval:(NSTimeInterval)interval delay:(NSTimeInterval)delay 
    [UIView animateWithDuration:interval
                          delay:delay
                        options:UIViewAnimationOptionCurveLinear
                     animations:^
                         self.label.frame = _labelDestRect;
                         self.subLabel.frame = _subLabelDestRect;
                     
                     completion:^(BOOL finished) 
                         if (finished) 
                             if (self.subLabel.frame.origin.x > 0) 
                                 [self prepareFramesForStep2];
                              else 
                                 [self prepareFramesForStep1];
                             

                             [self scrollAwayWithInterval:interval delay:delay];
                         
                     ];

我需要一种暂停/恢复动画的方法,所以我想用CABasicAnimation 做同样的动画。

所以我的问题是,用CABasicAnimation 制作以下动画的等效方法是什么?

【问题讨论】:

您是在问是否存在线性无限重复的 CABasicAnimation,还是在问我们将您的代码翻译成 Core Animation 代码? ;) @DavidRönnqvist 第二个选项。例如,我不知道是否可以为动画设置完成块 【参考方案1】:

实际上可以暂停 UIView 动画。它之所以有效,是因为在幕后,ios 在您正在制作动画的视图层上创建 CAAnimations。我在 github 上有一个名为 KeyframeViewAnimations 的示例项目,它正是展示了这一点。

如果您同时为 2 个不同的视图设置动画,您可能需要在包含两个视图的父视图层上操作 speed 属性,或者分别暂停两个视图层上的动画。 (我之前没有尝试过同时在多个视图上暂停 UIView 动画,所以我不完全确定在 superview 的图层上设置 speed 属性是否有效。)

编辑:我刚试过,在超级视图的图层上设置速度会暂停两个动画。我放在暂停/恢复按钮上的暂停/恢复代码如下所示:

- (IBAction)handlePauseButton:(UIButton *)sender

  animationIsPaused = !animationIsPaused;
  if (animationIsPaused)
  
    [pauseButton setTitle: @"Resume" forState: UIControlStateNormal];
    CALayer *theLayer = animationContainerView.layer;

    //Freeze the animation.
    theLayer.speed = 0;

    //Calculate how far we into the animation based on current media time minus the media time when
    //The animation started.

    //Shift the layer's timing so it appears at the current time.
    theLayer.timeOffset = CACurrentMediaTime()-theLayer.beginTime;
    theLayer.beginTime = 0;
  
  else
  
    [pauseButton setTitle: @"Pause" forState: UIControlStateNormal];
    CALayer *theLayer = animationContainerView.layer;

    CFTimeInterval pausedTime = [theLayer timeOffset];

    //Now reset the time offset and beginTime to zero.
    theLayer.timeOffset = 0.0;
    theLayer.beginTime = 0.0;

    //Figure out how much time has elapsed since the animation was paused.
    CFTimeInterval timeSincePause = CACurrentMediaTime() - pausedTime;

    //Set the layer's beginTime to that time-since-pause
    theLayer.beginTime = timeSincePause;

    //Start the animation running again
    theLayer.speed = 1.0;
  

【讨论】:

【参考方案2】:

你仍然可以使用这个块。

您只需要添加一个 BOOL 变量,您可以通过按下按钮(或任何您想要的方式)将其设置为 NO,然后将其设置为:

- (void)scrollAwayWithInterval:(NSTimeInterval)interval delay:(NSTimeInterval)delay 
    [UIView animateWithDuration:interval
                          delay:delay
                        options:UIViewAnimationOptionCurveLinear
                     animations:^
                         self.label.frame = _labelDestRect;
                         self.subLabel.frame = _subLabelDestRect;
                     
                     completion:^(BOOL finished) 
                         if (finished) 
                             if (shouldContinueAnimation) 
                                 if (self.subLabel.frame.origin.x > 0) 
                                     [self prepareFramesForStep2];
                                  else 
                                     [self prepareFramesForStep1];
                                 

                                 [self scrollAwayWithInterval:interval delay:delay];
                             
                         
                     ];

shouldContinueAnimation 是您的 BOOL。

希望对你有帮助。

【讨论】:

我希望能够暂停动画,这意味着它应该停止在我停止它的位置。您的解决方案会等到完成。

以上是关于CABasicAnimation 代替 UIView 动画的主要内容,如果未能解决你的问题,请参考以下文章

CABasicAnimation使用总结

如何在动画 CABasicAnimation 时改变速度

使用 UINavigationController 滑动边缘时 CABasicAnimation 重置

如何使用 CABasicAnimation 更改 Frame.size

CABasicAnimation animationWithKeyPath 一些规定的值

UIPercentDrivenInteractiveTransition 与 CABasicAnimation