层支持的NSView兄弟姐妹是否允许重叠?

时间:2012-05-23 12:37:22

标签: cocoa core-animation calayer nsview

我有点困惑。 Apple Documentation说明了这一点:

  

注意:出于性能原因,Cocoa不强制执行裁剪   兄弟视图或保证正确的失效和绘图行为   当兄弟视图重叠时。如果你想在前面绘制一个视图   另一种观点,你应该让前视图成为子视图(或后代)   后视图。

因此,根据这一点,兄弟视图不应重叠,否则行为未定义。

然而,在Cocoa Slides demo app中,由图层支持的NSView兄弟重叠,它似乎工作正常:

Cocoa Slides screenshot

Cocoa Slides示例代码是错误的,它只是一个巧合,它是否有效,或者文档是否过时了?从10.5开始过时,那是吗?

5 个答案:

答案 0 :(得分:9)

在Leopard及更高版本上,重叠视图可以正常工作,是否支持图层。

答案 1 :(得分:7)

经过一番研究,似乎Apple文档确实已经过时了。

自10.5以来,允许层支持的NSView兄弟重叠。

这个discussion from 2009,涉及Apple工程师David Duncan和Corbin Dunn最终提供了一些明确的答案:

  

重叠视图适用于Leopard,但在此之前不起作用。该   文件已过时。

     
    

我有一组视图,每个视图里面有很多小视图,     需要以相同的方式重叠呈现     在窗户上方,以便可以通过彼此看到它们。在我的     初步测试,我把每个大观点都视为单一的兄弟     背景视图。计划将每个人带到前面,     必要时通过重新安排z顺序。有没有未来(或     现在)在这个appoach?

  
     

这将适用于Leopard。

来源:http://www.cocoabuilder.com/archive/cocoa/228191-nsview-behaves-different-on-10-4-vs-10-5.html#228983

更新 James Dempsey also replied on Twitter

  

我的理解是重叠的兄弟视图从10.5开始就可以了,无论是否支持层。

答案 2 :(得分:4)

图层支持的视图由OpenGL分层(好吧,Quartz合成器,但它有助于将每个图层视为一个带有OpenGL纹理的多边形),因此它们始终支持正确的重叠。

CocoaBuilder / Cocoa-Dev上的线程根本没有提到层。这意味着它在没有支持CALayer的情况下谈论常规NSView(或者更确切地说,整个窗口只有一个CALayer)。

提到的一个例外是OpenGLView(同样没有图层),它总是在窗口顶部合成OpenGL矩形,删除任何子视图。我不认为制作NSOpenGLView图层支持的工作,但可以使用OpenGL图层,它将在其他图层之间正确合成。

另一个例外是非图层支持视图之上的图层,这是有道理的,因为所有非图层支持的视图都有效地存在于单个图层中,当然这个图层低于其任何子图层(托管在非图层支持的父视图中的支持视图必须是)。

因此,简而言之,它适用于非分层的10.5,因为永远支持图层支持的视图,当您混合使用或使用OpenGL时需要注意。

PS - 我并非100%确定重叠的非层支持视图的声明应该被视为规范。这是Apple工程师的非正式声明。事情本来可以改变,可能已经发现了使事情变得不起作用的错误。我想在正确重叠时使用图层。

答案 3 :(得分:2)

对某人可能有用:我在MacOS 10.7+上闪烁重叠的非分层子视图时出现问题。在我的应用程序中,视图用于渲染有关所选图形对象(选择框,缩放控制点等)的一些信息,因此它们有一些动画 - 这就是我的关键。

似乎重叠的兄弟姐妹即使没有图层也能正常工作,但在更简单的情况下。我有一堆动画视图,每个视图都有自己的计时器 - 然后它会闪烁。我找到了两个解决方案:打开图层同步动画,切换到单个共享计时器并同时更新所有视图。

至少这个技巧在我的应用程序中有所帮助,因为我不想使用这些图层。

答案 4 :(得分:1)

通常允许NSView兄弟姐妹重叠。有一件事可能会打击你,默认情况下NSScrollView是如何工作的。当你的兄弟NSScrollView与兄弟视图重叠时,事情会中断。

这是因为NSClipView只绘制了滚动视图的一部分并复制了未更改的内容。当您有与滚动视图重叠的同级视图时,此优化不起作用,即使它们只是兄弟,视图似乎也会滚动。

要使重叠的兄弟视图工作,即使它们不是图层支持,您也必须禁用此优化:

[scrollView.contentView setCopiesOnScroll:NO];