我刚刚第一次学习了一些基本的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个变量进行动画处理。
然而,令我惊讶的是,这“只是奏效了”。不知何故,该语言似乎已自动确定我想要为r
,g
和b
制作动画。编译器是否真的反省了这个块?这里发生了什么? animateWithDuration
如何知道我希望它随时间修改哪些变量?
提前致谢。
答案 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将是一个合乎逻辑的猜测)。我们有每个元素的起始值和结束值,并且它会在动画持续时间内发生变化。