首页 文章

是否允许使用图层托管NSView进行子视图?

提问于
浏览
7

层托管NSView(因此为您提供CALayer实例的NSView并使用 setLayer: 设置它)显然可以包含子视图 . 为什么显然?因为在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中它显示为:

使用图层托管视图时,不应依赖视图进行绘制,也不应将子视图添加到图层托管视图 .

什么是真的?示例代码是否不正确,它只是巧合才有效?或者文档是假的(我怀疑)?或者是否可以,因为子视图是通过动画师代理添加的?

3 回答

  • 19

    当AppKit是“图层托管”时,我们假设您可能(或可能不)拥有AppKit不知道的整个图层子树 .

    如果将子视图添加到图层托管视图,则它可能不会以您想要的正确兄弟顺序出现 . 另外,我们有时会添加和删除它们,因此它可能会根据您调用setLayer:,setWantsLayer:或何时从superview添加或删除视图而更改 . 在Lion(和之前),我们从窗口(或superview)中删除视图时删除我们“拥有”的图层(即:图层支持) .

    可以添加子视图......如果您有不是NSView的兄弟层,那么它们在子图层数组中的子兄弟顺序可能不是确定性的 .

  • 0

    我没有回答这个问题 . 但我确实认为CocoaSlides示例在文档所说的范围内起作用.2467813_ . 在该示例中,查看调用 insertNodeForAssetAtIndex: 方法的位置,您将看到它仅在填充视图时,在分配图层或具有setWantsLayer:调用它之前发生 .

    文档不包含任何子视图,他们只是说您无法添加和子视图 . 在添加这些子视图的时间点,主视图尚未成为图层托管视图 . 通过为其分配手动创建的图层将其转换为图层托管视图后,不再添加子视图 .

    所以文档和这个特定的例子之间确实没有矛盾 . 话虽如此,进一步探索这一点可能会很有趣,可能是通过从一开始就打开QC背景层,例如在 initWithFrame: 内粘贴一个 [self setUsesQuartzCompositionBackground:YES]; 右边 .

    SPOLIER ALERT: 似乎工作得很好 . 显示器的创建速度有点慢(所有QC动画都在进行中并不令人惊讶),但除此之外它一帆风顺 .

  • 1

    关于Apple代码的一条评论:它被破坏了 .

    当您第一次启动应用程序时,请注意好的渐变背景 . 打开QC,然后关闭 .

    噗,没有更多的渐变背景 .

相关问题