animateWithDuration如何知道动画的内容?

时间:2012-12-14 17:24:17

标签: objective-c ios

我刚刚第一次学习了一些基本的Objective-C和iOS开发,所以请耐心等待。我非常熟悉其他语言的lambdas概念,但这是我第一次使用Objective-C块。

所以,在UIKit动画教程之后,我想我会通过动画背景颜色来扩展它。我写了这个:

- (void) setBG: (float)r g:(float)g b:(float)b duration:(float)secs
{
    [UIView animateWithDuration:secs delay:0.0 options:0
                     animations:^{
                         [self setBackgroundColor: [UIColor colorWithRed:r green:g blue:b alpha:1.0]];
                     }
                     completion:nil];
}

所以,我希望能以某种方式告诉animateWithDuration需要动画的变量。我从一个动画一个位置(例如,x和y)的示例开始,并认为我可能需要对3个变量进行动画处理。

然而,令我惊讶的是,这“只是奏效了”。不知何故,该语言似乎已自动确定我想要为rgb制作动画。编译器是否真的反省了这个块?这里发生了什么? animateWithDuration如何知道我希望它随时间修改哪些变量?

提前致谢。

3 个答案:

答案 0 :(得分:2)

编译器不会以这种方式解释您的代码。它完全由UIView类完成。

我显然不清楚确切的内部实现,但一种可能的方法是在shouldAnimate中使用UIView标志。在执行您传递的动画块之前,animateWithDuration:...类方法可以打开此标志。然后,UIView的可动画属性的setter方法可能会检查此标志以确定是否需要设置动画:

- (void)setBackgroundColor:(UIColor *)newColor {
    if (shouldAnimate) {
        // set up and start animation.
    } else {
        _backgroundColor = newColor;  // just set without animating.
    }
    [self setNeedsDisplay];
}

执行动画块后,animateWithDuration:...最终再次关闭该标志,因此当您在动画块外设置任何UIView属性时,它不会被动画化。

答案 1 :(得分:2)

UIView类具有私有变量,可跟踪您是否在动画块内,以及动画的参数是什么。

各种UIView属性的setter检查该状态。如果setter发现它在动画块中被调用,它会为该属性创建一个动画。 (动画是附加视图图层的CABasicAnimation的实例。)

动画属性列在UIView Class Reference

  • frame
  • bounds
  • center
  • transform
  • alpha
  • backgroundColor
  • contentStretch

答案 2 :(得分:0)

UIView animateWithDuration在起始状态(原始值)和结束状态(您在动画块中设置的值)之间使用线性插值。想象一下变量值随时间变化的图表。使用所需的持续时间和两个点,它会在(0秒,起始值)和(持续时间,结束值)之间创建一条线。在动画播放时,值会根据随时间线移动的点进行更新。

所以,我相信颜色被分解为数值(rgb将是一个合乎逻辑的猜测)。我们有每个元素的起始值和结束值,并且它会在动画持续时间内发生变化。