【问题标题】:is there a way to run 2 NSAnimation objects simultaneously?有没有办法同时运行 2 个 NSAnimation 对象?
【发布时间】:2012-04-27 07:59:08
【问题描述】:

我创建了 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。问题是它同步运行,第二个动画在第一个动画结束后立即开始。有没有办法同时运行它们?

【问题讨论】:

  • 第二个动画在哪里?以及在哪些方面没有奏效?

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


【解决方案1】:

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

相反,您应该使您的视图符合NSAnimatablePropertyContainer 协议。

然后您可以将多个自定义属性设置为动画(除了NSView 已经支持的属性),然后您可以简单地使用视图的animator 代理来为属性设置动画:

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];

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

【讨论】:

  • 非常感谢!我不知道这个。不知何故,我没有在谷歌搜索中找到它。会尝试并告诉你。
  • 我只是好奇:如果我们遇到 NSAnimation 的性能(低帧率)问题,应用这个协议可能会有所帮助吗?
  • 这不是你的做法。您只需要在任何动画属性更改时重新绘制视图,并根据这些属性的当前值更新视图中的任何内容。我创建了一个示例项目,您可以看到它是多么简单:github.com/rkeniger/Animating-View
  • 差不多就是这样。
  • 这已经很老了,但对我很有帮助,所以我想进去说声谢谢!
猜你喜欢
  • 2010-10-23
  • 1970-01-01
  • 2018-02-07
  • 1970-01-01
  • 1970-01-01
  • 2016-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多