2011-05-19 37 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