有没有办法同时运行2个NSAnimation对象?

时间:2012-04-15 21:56:51

标签: objective-c cocoa osx-lion core-image nsanimation

我创建了2个NSAnimation个对象,用另一个视图翻转视图。我想同时运行2个这些动画。我不能使用NSViewAnimation,因为现在它正在为任何视图属性设置动画。

这是动画制作:

self.animation = [[[TransitionAnimation alloc] initWithDuration:1.0 animationCurve:NSAnimationEaseInOut] autorelease];
[self.animation setDelegate:delegate];
[self.animation setCurrentProgress:0.0];

[self.animation startAnimation];

我试图链接2个动画,但可能由于某种原因它不起作用。我举了一个例子: Apple developer site

配置NSAnimation对象以使用NSAnimationNonblocking根本不会显示任何动画......

编辑:第二个动画与第一个动画完全相同,并在创建第一个动画的同一个地方创建。

TransitionAnimationNSAnimation的子类,其中setCurrentProgress看起来像这样:

- (void)setCurrentProgress:(NSAnimationProgress)progress {
    [super setCurrentProgress:progress];
    [(NSView *)[self delegate] display];    
}
在这种情况下,delegateNSView,其drawRect函数在CIFilter上应用与时间相关的CIImage。问题是它运行同步,第二个动画在第一个动画结束后立即开始。有没有办法同时运行它们?

1 个答案:

答案 0 :(得分:17)

NSAnimation并不是同时动画多个对象及其属性的最佳选择。

相反,您应该使您的观点符合NSAnimatablePropertyContainer协议。

然后,您可以将多个自定义属性设置为动画(除NSView已支持的属性外),然后您只需使用视图“animator代理动画属性:< / p>

yourObject.animator.propertyName = finalPropertyValue;

除了使动画非常简单之外,它还允许您使用NSAnimationContext同时为多个对象设置动画:

[NSAnimationContext beginGrouping];
firstObject.animator.propertyName = finalPropertyValue1;
secondObject.animator.propertyName = finalPropertyValue2;
[NSAnimationContext endGrouping];

您还可以设置持续时间并提供完成处理程序块:

[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.5];
[[NSAnimationContext currentContext] setCompletionHandler:^{
    NSLog(@"animation finished");
}];
firstObject.animator.propertyName = finalPropertyValue1;
secondObject.animator.propertyName = finalPropertyValue2;
[NSAnimationContext endGrouping];

NSAnimationNSViewAnimation类比动画制作代理支持更早,我强烈建议您尽可能远离它们。支持NSAnimatablePropertyContainer协议比管理所有NSAnimation委托内容更简单 。 Lion支持自定义计时功能和完成处理程序意味着不再需要这样做了。

对于标准NSView对象,如果要向视图中的属性添加动画支持,只需在视图中覆盖+defaultAnimationForKey:方法并返回属性的动画:

//declare the default animations for any keys we want to animate
+ (id)defaultAnimationForKey:(NSString *)key
{
    //in this case, we want to add animation for our x and y keys
    if ([key isEqualToString:@"x"] || [key isEqualToString:@"y"]) {
        return [CABasicAnimation animation];
    } else {
        // Defer to super's implementation for any keys we don't specifically handle.
        return [super defaultAnimationForKey:key];
    }
}

我创建了一个简单的sample project,它展示了如何使用NSAnimatablePropertyContainer协议同时为视图的多个属性设置动画。

要成功更新所需的所有视图都要确保在修改任何可设置动画的属性时调用setNeedsDisplay:YES。然后,您可以在drawRect:方法中获取这些属性的值,并根据这些值更新动画。

如果您想要一个类似于NSAnimation工作方式的简单进度值,您可以在视图中定义progress属性,然后执行以下操作:

yourView.progress = 0;
[yourView.animator setProgress:1.0];

然后,您可以在self.progress方法中访问drawRect:,以找出动画的当前值。