图层托管NSView(因此您为其提供CALayer实例并使用setLayer:
设置它的NSView)显然可以包含子视图。为什么显然?因为在Apple自己的Cocoa Slides sample code project中,您可以选中一个复选框,将AssetCollectionView
从图层备份切换为图层托管:
- (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中,它显示为:
使用图层托管视图时,不应依赖视图 绘图,也不应该将子视图添加到图层托管视图。
什么是真的?示例代码是否不正确,它只是巧合才有效?或者文档是假的(我怀疑)?或者它是否正常,因为子视图是通过动画师代理添加的?
答案 0 :(得分:19)
当AppKit是“图层托管”时,我们假设您可能(或可能不)拥有AppKit不知道的整个图层子树。
如果您将子视图添加到图层托管视图,则它可能不会以您想要的正确兄弟顺序显示。另外,我们有时会添加和删除它们,因此它可能会根据您调用setLayer:,setWantsLayer:或何时从superview添加或删除视图而更改。在Lion(和之前),我们从窗口(或superview)中删除视图时删除我们“拥有”的图层(即:图层支持)。
可以添加子视图......如果您的兄弟图层不是NSView,那么它们在子图层数组中的子兄弟顺序可能不具有确定性。
答案 1 :(得分:1)
我不知道对此有什么“正确”的答案。但我确实认为CocoaSlides示例在文档说“你不应该”做的范围内工作。在示例中,查看调用insertNodeForAssetAtIndex:
方法的位置,您将看到它仅在填充视图时发生,之前它被分配了一个层或具有setWantsLayer :拜访它。
文档没有说图层托管的视图不能包含任何子视图,他们只是说你不能添加和子视图。在添加这些子视图的时间点,主视图尚未成为图层托管视图。通过为其分配手动创建的图层将其转换为图层托管视图后,不再添加子视图。
因此,文档和这个特定的例子之间确实没有矛盾。话虽如此,进一步探索这一点可能会很有趣,可能是通过从一开始就打开QC背景层,例如将[self setUsesQuartzCompositionBackground:YES];
右侧放在initWithFrame:
内。
SPOLIER ALERT: 它似乎工作得很好。显示器的创建速度稍慢(所有QC动画都在进行中就不足为奇了),但除此之外它还是一帆风顺。
答案 2 :(得分:0)
关于Apple代码的一条评论:它被破坏了。
首次启动应用程序时,请注意漂亮的渐变背景。打开QC,然后关闭。
噗,没有更多的渐变背景。