2012-05-23 84 views
7

圖層託管NSViews(因此您提供CALayer實例並將其設置爲setLayer:的NSViews)顯然可以包含子視圖。爲什麼顯然?因爲在蘋果自己的Cocoa Slides sample code project,您可以檢查被層爲後盾,以被層託管切換AssetCollectionView複選框:圖層託管NSView允許有子視圖嗎?

- (void)setUsesQuartzCompositionBackground:(BOOL)flag { 
    if (usesQuartzCompositionBackground != flag) { 
     usesQuartzCompositionBackground = flag; 

     /* We can display a Quartz Composition in a layer-backed view tree by 
      substituting our own QCCompositionLayer in place of the default automanaged 
      layer that AppKit would otherwise create for the view. Eventually, hosting of 
      QCViews in a layer-backed view subtree may be made more automatic, rendering 
      this unnecessary. To minimize visual glitches during the transition, 
      temporarily suspend window updates during the switch, and toggle layer-backed 
      view rendering temporarily off and back on again while we prepare and set the 
      layer. 
     */ 
     [[self window] disableScreenUpdatesUntilFlush]; 
     [self setWantsLayer:NO]; 
     if (usesQuartzCompositionBackground) { 
      QCCompositionLayer *qcLayer = [QCCompositionLayer compositionLayerWithFile:[[NSBundle mainBundle] pathForResource:@"Cells" ofType:@"qtz"]]; 
      [self setLayer:qcLayer]; 
     } else { 
      [self setLayer:nil]; // Discard the QCCompositionLayer we were using, and let AppKit automatically create self's backing layer instead. 
     } 
     [self setWantsLayer:YES]; 
    } 
} 

同樣AssetCollectionView類,子視圖增加了應顯示的每個圖像:

- (AssetCollectionViewNode *)insertNodeForAssetAtIndex:(NSUInteger)index { 
    Asset *asset = [[[self assetCollection] assets] objectAtIndex:index]; 
    AssetCollectionViewNode *node = [[AssetCollectionViewNode alloc] init]; 
    [node setAsset:asset]; 
    [[self animator] addSubview:[node rootView]]; 
    [nodes addObject:node]; 

    return [node autorelease]; 
} 

當我構建並運行應用程序並使用它時,一切似乎都沒有問題。

然而,在Apple's NSView Class Reference for the setWantsLayer: method記載:

當使用一個層託管視圖,你不應該依賴於 圖紙來看,也不應該添加子視圖層託管視圖。

什麼是真的?示例代碼是否有誤,它只是巧合而已?或者是文檔錯誤(我懷疑)?還是可以的,因爲子視圖是通過動畫代理添加的?

回答

19

當AppKit是「圖層託管」時,我們假設您可能(或可能不)具有AppKit不知道的整個圖層子樹。

如果您將子視圖添加到圖層託管視圖,那麼它可能不會以您想要的右側兄弟順序出現。另外,我們有時會添加和刪除它們,因此它可能會根據您何時調用setLayer :, setWantsLayer:或者何時添加或從超級視圖中刪除視圖而更改。在Lion上(以及之前),當視圖從窗口(或超級視圖)中刪除時,我們刪除我們「擁有」的圖層(即:圖層支持)。

可以添加子視圖...如果您的兄弟圖層不是NSView,則子圖層數組中的子級兄弟順序可能不是確定性的。關於蘋果這個代碼

+0

謝謝非常非常! –

1

我不知道什麼是「正確」的答案。但我確實認爲CocoaSlides示例在文檔所說的「不應該」做的範圍內工作。在該示例中,查看insertNodeForAssetAtIndex:方法的調用方式,您將看到它僅在填充視圖時發生,之前被分配了一個圖層或具有setWantsLayer:對其調用。

文檔沒有說層次託管的視圖不能包含任何子視圖,他們只是說,你不能添加和子視圖到一個。在添加子視圖的時候,主視圖還沒有成爲圖層託管視圖。在通過手動創建的圖層分配給圖層託管視圖後,不再添加子視圖。

所以文檔和這個特定的例子之間確實沒有矛盾。也就是說,進一步探索這一點可能會很有趣,可能是從一開始就打開QC背景層,例如,通過堅持內initWithFrame:[self setUsesQuartzCompositionBackground:YES];

SPOLIER ALERT: 它似乎工作得很好。顯示屏的創建速度稍慢(對於所有QC動畫而言並不令人意外),但除此之外,它是順暢的航行。

+0

謝謝,傑克!關於「添加」與「已有」子視圖有趣的觀察。也許文檔是過時的,因爲他們是這個問題太:http://stackoverflow.com/questions/10720062/are-layer-backed-nsview-siblings-allowed-to-overlap/10720422#10720422 –

0

一個評論:它打掉。

當你第一次啓動應用程序時,請注意漂亮的漸變背景。開啓QC,然後關閉。

噗,沒有更多的漸變背景。