2011-05-19 41 views
7

我试图在使用核心动画的NSView中滑动。我认为我需要使用明确的动画,而不是依赖诸如[[view animator] setFrame:newFrame]之类的东西。这主要是因为我需要设置动画委托才能在动画完成后采取行动。使用核心动画显式动画的NSView

我把它用动画师工作得很好,但正如我所说的,我需要在动画结束通知。我的代码目前的样子:

// Animate the controlView 
NSRect viewRect = [controlView frame]; 
NSPoint startingPoint = viewRect.origin; 
NSPoint endingPoint = startingPoint; 
endingPoint.x += viewRect.size.width; 
[[controlView layer] setPosition:NSPointToCGPoint(endingPoint)]; 

CABasicAnimation *controlPosAnim = [CABasicAnimation animationWithKeyPath:@"position"]; 
[controlPosAnim setFromValue:[NSValue valueWithPoint:startingPoint]]; 
[controlPosAnim setToValue:[NSValue valueWithPoint:endingPoint]]; 
[controlPosAnim setDelegate:self]; 
[[controlView layer] addAnimation:controlPosAnim forKey:@"controlViewPosition"]; 

这个视觉工作(和我在最后通知),但它看起来像实际controlView没有得到感动。如果我导致窗口刷新,controlView消失。我试着用

[controlView setFrame:newFrame]; 

更换

[[controlView layer] setPosition:NSPointToCGPoint(endingPoint)]; 

而且确实会导致视图(和层)移动,但它破坏的东西,使得我的应用程序与赛格故障去世不久。

最明确动画的例子似乎只能移动CALayer。必须有办法移动NSView并且也可以设置委托。任何帮助,将不胜感激。

回答

5

我认为你需要调用末SETPOSITION功能(设置动画后)。 此外,我不认为你应该明确地动画视图的层,而是使用动画师和设置动画的视图本身。您也可以使用代表与动画师:)

// create controlPosAnim 
[controlView setAnimations:[NSDictionary dictionaryWithObjectsAndKeys:controlPosAnim, @"frameOrigin", nil]]; 
[[controlView animator] setFrame:newFrame]; 
+0

感谢您的回复。我确实通过对代码进行了一些重新安排来完成这项工作。我认为苹果在WWDC期间的例子告诉你在设置动画之前操纵视图*。那么你如何使用动画师来使用代表?我已经搜索了很多关于这方面的例子,并且空着。我也看到许多帖子说这是不可能的。 – btschumy 2011-05-23 16:54:55

+0

将代理设置为您的controlPosAnim,将其添加到controlView的动画中,将调用委托方法。 – 2011-05-24 22:36:58

+0

好的感谢信息 – btschumy 2011-05-25 15:50:42

8

对视图所做的更改将在当前运行循环结束时生效。对于应用于图层的任何动画也是如此。

如果动画视图的层,视图本身不受影响这就是为什么视图显示在动画完成时跳回到原来的位置。

考虑到这两个东西,你可以通过视图的框架设置为你希望在动画完成它是什么,然后加上一个明确的动画视图的层得到你想要的效果。

当动画开始,它移动的视图到起始位置,它动画到结束位置,并且当动画完成,该视图有你指定的帧。

- (IBAction)animateTheView:(id)sender 
{ 
    // Calculate start and end points. 
    NSPoint startPoint = theView.frame.origin; 
    NSPoint endPoint = <Some other point>;  

    // We can set the frame here because the changes we make aren't actually 
    // visible until this pass through the run loop is done. 
    // Furthermore, this change to the view's frame won't be visible until 
    // after the animation below is finished. 
    NSRect frame = theView.frame; 
    frame.origin = endPoint; 
    theView.frame = frame; 

    // Add explicit animation from start point to end point. 
    // Again, the animation doesn't start immediately. It starts when this 
    // pass through the run loop is done. 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"]; 
    [animation setFromValue:[NSValue valueWithPoint:startPoint]]; 
    [animation setToValue:[NSValue valueWithPoint:endPoint]]; 
    // Set any other properties you want, such as the delegate. 
    [theView.layer addAnimation:animation forKey:@"position"]; 
} 

当然,为了这个代码的工作,你需要确保你的视图和它的超级视图都有图层。如果超级视图没有图层,则会显示损坏的图形。

+0

哇感谢最后评论超级和孩子的需要层,否则你会得到损坏的图形。这帮助我解决了一个完全不相关的问题。谢谢! – migs647 2014-07-08 16:41:11