8

在 iOS 中,您可以使用动画块为视图对象设置动画:

[UIView animateWithDuration:1.0 animations:^{

        firstView.alpha = 0.0;

        secondView.alpha = 1.0;

}];

我们这里有一个代码块,它描述了动画完成后视图属性最终会看到什么。

这是如何运作的?

我可以理解(我认为)如果这是使用某种声明性格式完成的,但从它的外观来看,动画块只是一段可能必须执行的常规代码,检查结果,然后有人将其转码为实际执行动画的低级图形代码。

该块是否实际执行(或以某种方式进行了逆向工程),如果是,何时执行?

如果这段代码是在动画开始之前执行的,那么为什么对引用的视图属性的更改没有立即反映呢?

如果我将代码放入不更改视图属性但执行其他操作的块中会发生什么?

4

3 回答 3

8

是的,该块实际上被调用了——然后它立即改变了视图的属性。UIView 的属性设置器负责查看该设置是否在动画上下文中使用——如果是,它们使用 CoreAnimation 和 CoreGraphics 计算动画帧等。

如果您将非动画代码放入这些块中,则不会发生任何特殊情况——该块将立即执行。

于 2012-07-13T08:57:12.533 回答
6

在块之前查看等效代码是有启发性的:

[UIView beginAnimations:@"foo" context:NULL];
[UIView setAnimationDuration:1.0];
firstView.alpha = 0.0;
secondView.alpha = 1.0;
[UIView commitAnimations];

所以你看,即使在块之前,要更改的属性也是直接设置的;但是,它们不会立即生效(它们是动画的)。

它是如何工作的?据推测,当您在视图上设置属性时,它会检查您是否已运行beginAnimations但未运行,如果是commitAnimations,则不会立即生效(而是将其添加到要为该动画制作动画的事物列表中)。

因此,块版本在 pre-blocks 版本的上下文中非常简单:您可以将其视为在内部beginAnimationscommitAnimations行中运行动画块。

于 2012-07-14T20:46:36.083 回答
1

苹果并没有真正谈论它是如何工作的细节,但我认为会发生这样的事情:

当视图添加到视图层次结构时,系统会在视图的所有可动画属性上添加 KVO 观察者。

当您的动画块执行时,系统会设置一个状态来监视这些属性上的 KVO 通知。然后,被调用的代码会创建适当的 CAAnimation 对象并将其添加到每个受影响的视图层。

于 2012-07-13T15:36:11.747 回答