免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何纠纷,均与本博客所有人、发表该翻译稿之人无任何关系。谢谢合作!
著作权声明:本文由http://blog.csdn.net/mengtnt翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,
核心动画是一个强大成熟的技术,运用它可以使你达到事半功倍的效果。为了执行动画,苹果公司提供了动画的代理对象,当它被调用时同时那些可视的组件,譬如视图的外框、透明度、或者位置改变时,就会自动的触发隐式的动画。对于基础的层动画,CABasicAnimation类通过提供一个开始值和一个结束值,来执行一个动画。这章,通过你的应用程序,我们来看一些执行动画的基础方法。
最简单的动画
由于核心动画集成到了cocoa中,因而你通过给窗口、视图、层简单的设定一些你感兴趣的属性值,从而使那些可视的组件做动画到新的值。当你使用CALayer的时候,你需要做的就是直接设置这些值。例如,如果你想改变一个层的边框大小,你简单的调用[layer setBounds:newFrame],这里要说的是,层是你已经创建的CALayer对象,并且要增加这个对象要层树中,而newFrame是一个CGRect包含了边框的尺寸和原点。当这些代码运行时,就会使用关键路径“bounds”的默认动画,使层具有边框大小改变时的动画。
简单的说,当你使用一个窗口(NSWindow)或者视图(NSView),你需要做的就是,使用了动画的代理对象,来设置窗口或者视图的属性值。这意味着,例如,你可以代替使用[view setFrame:newFrame]来设置窗口的框架,通过[[view animtor] setFrame:newFrame]这个函数调用,达到目的。不同之处就是,你用了一个动画的代理对象,设置了这些属性,而这些都会隐式的执行框架的初始值到结束值的动画。
动画的代理对象
因此什么是动画的代理对象哪?动画的代理在NSView和NSWindow上面都可用。它实现了NSAnimatablePropertyContainer的代理。这包含了使用键值编码对,当你需要做插值和在场景后面做动画时,来设定你指派的参数值。
顾名思义,动画代理就是一个媒介,来设定你给定的值,达到控制动画的属性,从开始或者目前的值,到结束的值。它设定了这些值,就像是你已经在这些属性上调用了一样。
在窗口、视图和层动画之间的不同
在窗口,视图和层之间的动画是一样的,然而实现却不同。这个段落中,我们将讨论你可能会想到的,最普通的动画的实现---框架的尺寸改变。
窗口尺寸改变
自从mac os x的第一个版本,动画一个窗口框架的能力已经可用,对于开发者来说,利用
-(void)setFrame:(NSRect)windowFrame
display:(BOOL)displayViews animate:(BOOL)performAnimation
来设定动画。第一个参数是你将要动画到的新框架。第二个参数告诉窗口在所有的子视图上面调用-displayIfNeeded,和第三个参数是告诉窗口以动画的方式,从目前的框架转换到新的框架。如果最后一个参数设定为NO,新的框架会立即改变,而不会有渐变的动画。
既然内嵌的窗口框架具有改变大小的能力,那么为什么你需要使用核心动画来改变窗口的框架那?答案是你不必。对于许多情况,当你改变尺寸的时候,你可能仅仅需要使用内嵌的功能就行了。然而,可能有这些情况,你想要在窗口动画上有更多的控制。当你要做这些的时候,记住一些事情。NSWindow就像NSView一样,有一个动画代理。当你调用动画者时,它会按照你指定的参数做动画,但是那些参数都是附带物。如果你想把一个窗口,在屏幕上移动到一个不同的位置,事实上,要么你用
- (void)setFrame:(NSRect)windowFrame
display:(BOOL)displayViews
这个方法(这个方法不要第三个参数),或者你可以增加动画到窗口本身的动画字典中。首先让我们看怎么来使用动画代理。如下:
[[window animator] setFrame:newFrame display:YES];
这个可以使你简单的动画窗口的框架。
默认的动画播放是0.25秒。如果你想改变这个时间,需要使用NSAnimationContext这个对象,对于CATransaction它是NSView/NSWindow的副本。如果我们利用NSAnimationContext封装调用-setFrame,我们可以指定动画的时间。表3-1演示了如何做:
- [NSAnimationContext beginGrouping];
- [[NSAnimationContext currentContext] setDuration:5.0f];
- [[window animator] setFrame:newFrame display:YES];
- [NSAnimationContext endGrouping];
List 3-1
这引起了框架的改变的时间为5秒,而非默认的0.25秒。你下一段即将看到,这种方法也是你能使用的,可以改变NSView的动画时间的。
使用核心动画的CABasicAnimation 也能够在窗口和视图上做动画,但是动画如何安装有点不同。作为通过在窗口动画代理调用-setFrame的替换者,我可以创建一个CABasicAnimation和动画框架的属性。下面在表3-2中可以看到如何在窗口创建、增加和运行基础动画。
- CABasicAnimation *animation =
- [CABasicAnimation animationWithKeyPath:@”frame”];
- [animation setFromValue:[NSValue valueWithRect:oldFrame]];
- [animation setToValue:[NSValue valueWithRect:newFrame]];
- [animation setDuration:5.0f];
- [window setAnimations:[NSDictionary animation forKey:@”frame”]];
- [[window animator] setFrame:newFrame display:YES];
表3-2 增加一个动画到窗口动画字典
这个动画的效果和表3-1是相同的。
视图的改变
视图和窗口同样能被改变,但是你要使用不同的关键路径。你可以在视图上使用-setFrame这个在窗口上使用的同样的代码。如图3-3
- [NSAnimationContext beginGrouping];
- [[NSAnimationContext currentContext] setDuration:5.0f];
- [[view animator] setFrame:newFrame display:YES];
- [NSAnimationContext endGrouping];
表3-3
仅仅的不同之处是,表3-1中调用的对象不同,这里是用的view
如果你想使用显示的动画,代替使框架做动画,你可以使框架原点和框架尺寸做动画。表3-4展示了如何使用这些属性做动画。
- CABasicAnimation *originAnimation = [CABasicAnimation
- animationWithKeyPath:@”frameOrigin”];
- [originAnimation setFromValue:[NSValue
- valueWithPoint:oldImageFrame.origin]];
- [originAnimation setToValue:[NSValue valueWithPoint:newFrame.origin]];
- [originAnimation setDuration:5.0];
- CABasicAnimation *sizeAnimation = [CABasicAnimation
- animationWithKeyPath:@”frameSize”];
- [sizeAnimation setFromValue: