CABasicAnimation和自定义类型 [英] CABasicAnimation and custom types

查看:89
本文介绍了CABasicAnimation和自定义类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对CoreAnimation不太熟悉,所以我希望我已经错过了一些简单的事情。我想用 [[view animator] setGradient:gradient]; 以简单的方式为NSView的自定义属性( NSGradient )设置动画。我定义了+ (id)defaultAnimationForKey:(NSString *)key 并返回了一个简单的CABasicAnimation,但是没有动画执行。由于这适用于较简单的类型和NSColor,因此我想CABasicAnimation不适用于渐变。很好,但是在这种特殊情况下,梯度是微不足道的(总是有两个停止点),因此我可以轻松编写插值函数。 问题:如何定义自定义插值?我搜寻了有关视图,图层和动画的代表,动画类的子类化等方面的代表,但是我无法弄清楚。谢谢!

I'm not very familiar with CoreAnimation, so I hope I've just missed something pretty simple. I want to animate a custom property (NSGradient) of a NSView in a simple manner, with [[view animator] setGradient:gradient];. I defined + (id)defaultAnimationForKey:(NSString *)key and returned a simple CABasicAnimation, however, no animation is executed. Since this works for simpler types and NSColor, I guess CABasicAnimation doesn't work with gradients. Fine, but in this particular case gradients are trivial (two stops, always), so I can easily write an interpolation functions. The question: how can I define a custom interpolation? I googled around regarding delegates on view, layer and animations, subclassing animation class etc., but I wasn't able to figure the things out. Thanks!

推荐答案

我想我记得我在学习如何使用Core Animation来演示如何设置时,通过了一些Apple文档。定义的动画所提供的properticode describees无法处理的动画。在此过程中,我偶然发现了一些来自Apple的示例代码,这些代码描述为:

I thought I remembered passing by some Apple documentation when I was learning how to use Core Animation that showed how to set up animations that couldn't be handled by properticode describedes that are supplied with defined animations. Along the way I stumbled across some sample code from Apple that is described as:


显示单个渐变层并使用新的随机变量对其进行连续动画处理颜色。

A single gradient layer is displayed and continuously animated using new random colors.

这可能是您已经用另一种方式处理的特定任务的答案。我在Xcode的《文档和API参考》中找到了它,示例代码的名称就是 Gradients 。 (请注意,有一个原始版本1.0和一个更新版本1.1,已于今年4月重做,因此应该易于使用当前工具使用。

That may be the answer to the specific task you already handled another way. I found it in the Documentation and API Reference within Xcode and the name of the sample code is simply Gradients. (Note that there is an original version 1.0 and an updated version 1.1 that was redone this year in April and so should be easier to use with current tools.

但是,创建不能由Core Animation本身自动执行的自定义动画的一个更大的问题是,遵循苹果可可动画编程指南中的示例,该示例位于使用NSAnimation对象部分在主题子类化NSAnimation 下进行了描述,推荐的方法显示在标题 Smooth Animations 下。您覆盖了 setCurrentProgress: 方法,以便每次调用该方法时,您首先调用 Super ,以便使 NSAnimation 更新进度值,即您的自定义动画属性,然后进行动画下一帧所需的任何更新或绘制。这是Appl提供的注释和示例代码引用文档中的e:

But, the larger question of creating a custom animation that can't be automated by Core Animation itself is to follow the example from Apple's Animation Programming Guide for Cocoa in the section Using an NSAnimation Object. It's described under the topic Subclassing NSAnimation and the recommended method is shown under the heading Smooth Animations. You override the setCurrentProgress: method so that each time it is called you first invoke Super so that NSAnimation updates the progress value, i.e., your custom animated property and then do any updating or drawing needed for the next frame of your animation. Here are the notes and example code provided by Apple in the referenced documentation:


如设置和处理进度标记中所述,您可以在NSAnimation上附加一系列进度标记。对象,并让委托实现animation:didReachProgressMark:方法以在每个进度标记处重绘对象。但是,这不是设置对象动画的最佳方法。除非您设置大量的进度标记(每秒30个或更多),否则动画可能会显得生涩。

As mentioned in "Setting and Handling Progress Marks," you can attach a series of progress marks to an NSAnimation object and have the delegate implement the animation:didReachProgressMark: method to redraw an object at each progress mark. However, this is not the best way to animate an object. Unless you set a large number of progress marks (30 per second or more), the animation is probably going to appear jerky.

更好的方法是将NSAnimation子类化并覆盖setCurrentProgress:方法,如清单4所示。NSAnimation对象在每个帧之后调用此方法以更改进度值。通过截取此消息,您可以执行该框架所需的任何重绘或更新。如果您确实覆盖了此方法,请确保调用super的实现,以便它可以更新当前进度。

A better approach is to subclass NSAnimation and override the setCurrentProgress: method, as illustrated in Listing 4. The NSAnimation object invokes this method after each frame to change the progress value. By intercepting this message, you can perform any redrawing or updating you need for that frame. If you do override this method, be sure to invoke the implementation of super so that it can update the current progress.



Listing 4  Overriding the setCurrentProgress: method
- (void)setCurrentProgress:(NSAnimationProgress)progress
{
    // Call super to update the progress value.
    [super setCurrentProgress:progress];

    // Update the window position.
    NSRect theWinFrame = [[NSApp mainWindow] frame];
    NSRect theScreenFrame = [[NSScreen mainScreen] visibleFrame];
    theWinFrame.origin.x = progress *
        (theScreenFrame.size.width - theWinFrame.size.width);
    [[NSApp mainWindow] setFrame:theWinFrame display:YES animate:YES];
}

因此,基本上,您定义了进度值(可能由多个值组成)定义自定义动画的状态并编写代码,以给出当前的进度值来绘制或更改当动画处于该特定状态时所绘制的内容。然后,让NSAnimation使用设置动画的常规方法来运行动画,它将执行您的代码以在适当的时间绘制动画的每一帧。

So basically you define a "progress value" (possibly composed of several values) that defines the state of your custom animation and write code that given the current "progress value" draws or changes what is drawn when the animation is at that particular state. Then you let NSAnimation run the animation using the normal methods of setting up an animation and it will execute your code to draw each frame of the animation at the appropriate time.

I希望能回答您想知道的事情。我怀疑我是否可以通过搜索而轻松地找到它,而之前却没有看到它,因为我终于不得不去我认为可能的位置,并逐页浏览整个主题以再次找到它!

I hope that answers what you wanted to know. I doubt I could have found this easily by searching without having seen it before since I finally had to go to where I thought it might be and skim page by page through the entire topic to find it again!

这篇关于CABasicAnimation和自定义类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆