Kev*_*tre 8 macos cocoa core-animation core-graphics objective-c
我有一个NSWindow
包含NSView
'Wants Core Animation Layer'的功能.然后视图包含许多NSImageView
使用最初动画到位置的视图.当我运行动画时,它非常缓慢并且掉落了大部分帧.但是,如果我禁用"想要核心动画层",动画效果很好.我将需要核心动画层,但无法弄清楚如何让它充分发挥作用.
我可以做些什么来解决性能问题吗?
这是代码:
// AppDelegate
NSRect origin = ...;
NSTimeInterval d = 0.0;
for (id view in views)
{
[view performSelector:@selector(animateFrom:) withObject:origin afterDelay:d];
d += 0.05f;
}
// NSImageView+Animations
- (void)animateFrom:(NSRect)origin
{
NSRect original = self.frame;
[self setFrame:origin];
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.20f];
[[self animator] setFrame:original];
[NSAnimationContext endGrouping];
}
Run Code Online (Sandbox Code Playgroud)
Nat*_*ror 10
它可能NSTimer
会扼杀你的表现.Core Animation对通过CAMediaTiming
协议控制动画的时间安排提供了丰富的支持,您应该在应用程序中利用它.而不是使用动画师代理,并NSAnimationContext
尝试直接使用核心动画.如果CABasicAnimation
为每个图像创建一个并设置它beginTime
,它将延迟动画的开始.此外,为了使延迟按照您想要的方式工作,您必须将每个动画包装在其中CAAnimationGroup
,并将其duration
设置为整个动画的总时间.
使用该frame
财产也可能导致经济放缓.我真的很想在这样的情况下利用这个transform
属性CALayer
,你正在做一个"开放"的动画.您可以在IB(或代码中)的最终位置布置图像,在窗口可见之前,将其变换修改为动画的起始位置.然后,您只需将所有转换重置为CATransform3DIdentity
以使接口进入正常状态.
我的<plug type ="无耻">即将推出的Core动画书</ plug>中有一个例子,它与你想要做的非常相似.它NSImageView
同时动画30 秒,没有丢帧.我为你修改了这个例子并把它放在github上.这些是代码中最相关的部分,其中删除了无关的UI内容:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// ... SNIP ... //
//Start with all of the images at the origin
[CATransaction begin];
[CATransaction setDisableActions:YES];
for (CALayer *imageLayer in [[[self imageContainer] layer] sublayers]) {
CGPoint layerPosition = [layer position];
CATransform3D originTransform = CATransform3DMakeTranslation(20.f - layerPosition.x, -layerPosition.y, 0.f);
[imageLayer setTransform:originTransform];
}
[CATransaction commit];
}
Run Code Online (Sandbox Code Playgroud)
- (IBAction)runAnimation:(id)sender {
CALayer *containerLayer = [[self imageContainer] layer];
NSTimeInterval delay = 0.f;
NSTimeInterval delayStep = .05f;
NSTimeInterval singleDuration = [[self durationStepper] doubleValue];
NSTimeInterval fullDuration = singleDuration + (delayStep * [[containerLayer sublayers] count]);
for (CALayer *imageLayer in [containerLayer sublayers]) {
CATransform3D currentTransform = [[imageLayer presentationLayer] transform];
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform"];
anim.beginTime = delay;
anim.fromValue = [NSValue valueWithCATransform3D:currentTransform];
anim.toValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
anim.fillMode = kCAFillModeBackwards;
anim.duration = singleDuration;
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = [NSArray arrayWithObject:anim];
group.duration = fullDuration;
[imageLayer setTransform:CATransform3DIdentity];
[imageLayer addAnimation:group forKey:@"transform"];
delay += delayStep;
}
}
Run Code Online (Sandbox Code Playgroud)
如果您想查看该视频,我还会在YouTube上播放该视频的视频.
归档时间: |
|
查看次数: |
5541 次 |
最近记录: |