2014-01-06 65 views
0

在我的應用程序中有一些區域需要爲視圖添加動畫。但是,我不想讓視圖支持層。所以,我創建了第二個視圖(我們稱之爲animationView),該視圖託管了一個可以進行動畫處理的圖層。當然,爲了讓animationView看起來像實際視圖,我首先將視圖渲染成一個圖像,然後將其設置爲animationView的根層的內容。當所有這些完成後,我用animationView替換視圖。在這一點上,我可以使用CALayer動畫的所有強大功能,而無需支持實際的視圖層。下面是我所講述的代碼(我會得到我的問題在一分鐘內):小牛問題:替換子視圖時閃爍

// Creating an animationView 
NSView* animationView = [[NSView alloc] initWithFrame: self.bounds]; 
animationView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable; 
animationView.layer = [CALayer layer]; 
[animationView setWantsLayer: YES]; 

// Snapshotting the actual view 
NSBitmapImageRep* imageRep = [view bitmapImageRepForCachingDisplayInRect: view.bounds]; 
[view cacheDisplayInRect: view.bounds toBitmapImageRep: imageRep]; 
NSImage* image = [[NSImage alloc] initWithSize: [imageRep size]]; 

[image addRepresentation: imageRep]; 

// Replacing the view with animationView 
NSDisableScreenUpdates(); 

[CATransaction begin]; 
[CATransaction setDisableActions:YES]; 
layer.contents = image; 
[CATransaction commit]; 

[self replaceSubview: view with: animationView]; 

NSEnableScreenUpdates(); 

// Animate animationView 
// ... 

這工作完全在10.8和10.9上的動畫也發揮得很好,但在10.9 ONLY有一個當替換視圖時可見的閃爍。即使使用NS [禁用|啓用] ScreenUpdates後,我有這個問題。我還嘗試在// Animate animationView之後刪除整個動畫代碼,以便不播放動畫,並確保閃爍不是來自動畫,而是實際上來自替換視圖的動作。而且閃爍仍然存在。我真的不明白爲什麼OS版本之間的區別......爲什麼會發生這種情況?

回答

1

這聽起來像有什麼東西在小牛瘋狂。你嘗試:

[self.window disableFlushWindow]; 
[self replaceSubview: view with: animationView]; 
[self.window enableFlushWindow]; 

另外,我注意到你要替換的子視圖「視圖」在這裏,但你與「自我」的內容替換「視圖」。什麼是'觀點'?

而且,你並不需要通話雙方:

animationView.layer = [CALayer layer]; 
[animationView setWantsLayer: YES]; 

而且,只要致電:

[CATransaction setDisableActions:YES]; 
+0

不,我還沒有嘗試過,但我會,謝謝你的建議。我以後會告訴你它是怎麼回事。對於這種自我/觀點混淆感到抱歉,我的錯誤:我實際上有自己的觀點。另外,感謝CATransaction上的提示!從文檔中錯過了。 – Alex

+0

另外,關於'setWantsLayer'方法調用,文檔聲明:'要創建一個圖層託管視圖,您必須調用setLayer:並在調用setWantsLayer:方法之前提供圖層對象;這些方法調用的順序是至關重要的。「我認爲這意味着需要按特定順序調用這兩種方法。你是說我只需要調用'setLayer'? – Alex

+0

沒錯,但是如果你只是想將它設置爲一個通用的CALayer,那麼只需調用「animationView.wantsLayer = YES」並讓AppKit機制爲你創建一個自定義層即可。該文檔適用於您想使用自定義圖層子類(如CATiledLayer)的情況。 –

-1

請嘗試使用GCD替換主隊列的子視圖(在這種情況下,並塊)。這可能會解決您的問題。

dispatch_sync(dispatch_get_main_queue(), ^{ 
    // Your action here 
}); 
+0

整個代碼在主線程上運行(單擊按鈕時運行),因此不能成爲問題的根源。 – Alex

+0

好的,會嘗試重現這個問題並很快回來:) – Ashutosh