Overlapping sibling views

  • Hi, I had to design my whole view system to work around the problems with overlapping sibling views not being guaranteed to be drawn in a specific order, but today I came across some posts that suggested that this was no longer the case.

    In the current 10.8 documentation it still says: "Note: For performance reasons, Cocoa does not enforce clipping among sibling views or guarantee correct invalidation and drawing behavior when sibling views overlap. If you want a view to be drawn in front of another view, you should make the front view a subview (or descendant) of the rear view."

    But in this thread from 2009, two Apple engineers (Corbin Dunn and David Duncan) said that the documentation is out of date, and that it should work as of 10.5: http://www.cocoabuilder.com/archive/cocoa/228191-nsview-behaves-different-o
    n-10-4-vs-10-5.html


    There are conflicting views expressed in http://stackoverflow.com/questions/466297/is-there-a-proper-way-to-handle-o
    verlapping-nsview-siblings


    My scenario is a whole lot of sibling, potentially translucent, overlapping, layer backed views.

    I'm fairly sure I tested this and found it to fail in mid 2010, so this would make it 10.6.

    It also appears that the CocoaSlides example app uses sibling views for the slides, and that appears to show the slides in the same order every time.

    So, is the problem actually fixed? And if so, what version of the operating system introduced the fix?

    Regards

    Gideon
  • The docs are out of date. Overlapping views work properly as of 10.5 (albeit you might run into performance problems if you push it too far). Please use the feedback thing on the bottom of the docs to let Apple know it's wrong!

    On 30 Apr 2013, at 08:39, Gideon King <gideon...> wrote:

    > Hi, I had to design my whole view system to work around the problems with overlapping sibling views not being guaranteed to be drawn in a specific order, but today I came across some posts that suggested that this was no longer the case.
    >
    > In the current 10.8 documentation it still says: "Note: For performance reasons, Cocoa does not enforce clipping among sibling views or guarantee correct invalidation and drawing behavior when sibling views overlap. If you want a view to be drawn in front of another view, you should make the front view a subview (or descendant) of the rear view."
    >
    > But in this thread from 2009, two Apple engineers (Corbin Dunn and David Duncan) said that the documentation is out of date, and that it should work as of 10.5: http://www.cocoabuilder.com/archive/cocoa/228191-nsview-behaves-different-o
    n-10-4-vs-10-5.html

    >
    > There are conflicting views expressed in http://stackoverflow.com/questions/466297/is-there-a-proper-way-to-handle-o
    verlapping-nsview-siblings

    >
    > My scenario is a whole lot of sibling, potentially translucent, overlapping, layer backed views.
    >
    > I'm fairly sure I tested this and found it to fail in mid 2010, so this would make it 10.6.
    >
    > It also appears that the CocoaSlides example app uses sibling views for the slides, and that appears to show the slides in the same order every time.
    >
    > So, is the problem actually fixed? And if so, what version of the operating system introduced the fix?
    >
    >
    > Regards
    >
    > Gideon
  • On Apr 30, 2013, at 00:39 , Gideon King <gideon...> wrote:

    > My scenario is a whole lot of sibling, potentially translucent, overlapping, layer backed views.

    I've never seen any evidence that sibling *NSView*s draw in the wrong order since 10.5. I believe that 'drawRect:' is correctly called in the back-to-front order of the sibling arrangement in the parent view.

    However, I *have* seen firsthand, in the last few weeks, that the layers of siblings under a layer-backed parent view were composited in a random order. In my case, I had two sibling views, and I observed the bottom one displaying "on top" unpredictably, about 50% of the time.

    To be clear, the layers didn't get re-ordered randomly every time they were drawn. The random order was baked into the view or layer hierarchy as part of the view initialization, and didn't change subsequently as long as the view existed.

    So from my own experience, I'd agree there is a problem, but I don't know where the problem lies. It may be nothing to do with layers. Perhaps there's currently a bug loading nibs that randomly re-orders sibling views. Perhaps the sibling order in the layer hierarchy doesn't match the order in the view hierarchy. Perhaps the hierarchies are correct but the layer compositing operation is wrong.
  • > I've never seen any evidence that sibling *NSView*s draw in the wrong order since 10.5. I believe that 'drawRect:' is correctly called in the back-to-front order of the sibling arrangement in the parent view.
    >
    > However, I *have* seen firsthand, in the last few weeks, that the layers of siblings under a layer-backed parent view were composited in a random order. In my case, I had two sibling views, and I observed the bottom one displaying "on top" unpredictably, about 50% of the time.
    Sorry for stepping in, but I have seen this behavior as well in the last week … I had this in the tree ...

    - NSView
      - NSView (layer backed for AVPlayer)
      - NSButton

    … and NSButton was invisible - to be more precise, this button wasn't drawn in correct order, but it did work = I was able to click on it. This invisibility was random. To fix correct drawing order, I had to set wantsLayer = YES on the root NSView as well. And then it was fixed and no more random invisibility.

    R.
  • On 30 Apr 2013, at 09:38, Robert Vojta <robert...> wrote:

    >> I've never seen any evidence that sibling *NSView*s draw in the wrong order since 10.5. I believe that 'drawRect:' is correctly called in the back-to-front order of the sibling arrangement in the parent view.
    >>
    >> However, I *have* seen firsthand, in the last few weeks, that the layers of siblings under a layer-backed parent view were composited in a random order. In my case, I had two sibling views, and I observed the bottom one displaying "on top" unpredictably, about 50% of the time.
    > Sorry for stepping in, but I have seen this behavior as well in the last week … I had this in the tree ...
    >
    > - NSView
    > - NSView (layer backed for AVPlayer)
    > - NSButton
    >
    > … and NSButton was invisible - to be more precise, this button wasn't drawn in correct order, but it did work = I was able to click on it. This invisibility was random. To fix correct drawing order, I had to set wantsLayer = YES on the root NSView as well. And then it was fixed and no more random invisibility.

    Layer-backed views always *appear* above non-layer-backed views. Effectively, all non-layer-backed views get rendered into a single layer that makes up the entire window.
  • On Tuesday, 30. April 2013 at 10:42, Mike Abdullah wrote:
    > Layer-backed views always *appear* above non-layer-backed views. Effectively, all non-layer-backed views get rendered into a single layer that makes up the entire window.

    Thanks, didn't know this. Never needed layer backed view until now because of AVPlayer ...
  • So it sounds as if as long as I have all my views in the entire hierarchy layer backed, my sibling views should always draw in order.

    This makes me happy :) … and the documentation wrong :(  - I'll report that.

    Regards

    Gideon
  • On 30 Apr 2013, at 16:53, Gideon King <gideon...> wrote:

    > So it sounds as if as long as I have all my views in the entire hierarchy layer backed, my sibling views should always draw in order.

    Yup. Bear in mind WebViews don't support being layer-backed (still!), which can throw a spanner in the works.
  • On Tue, 30 Apr 2013 01:30:00 -0700, Quincey Morris said:

    > On Apr 30, 2013, at 00:39 , Gideon King <gideon...>  wrote:
    >
    >> My scenario is a whole lot of sibling, potentially translucent,
    > overlapping, layer backed views.
    >
    > I've never seen any evidence that sibling *NSView*s draw in the wrong
    > order since 10.5. I believe that 'drawRect:' is correctly called in the
    > back-to-front order of the sibling arrangement in the parent view.
    >
    > However, I *have* seen firsthand, in the last few weeks, that the layers
    > of siblings under a layer-backed parent view were composited in a random
    > order.

    I've seen that too, you can reference:

    rdar://11852080
    Overlapping NSViews draw in wrong order when layer hosting/backing is involved
    Duplicate/10348980

    and:

    rdar://11805856
    'View Programming Guide' doc incorrect about overlapping views

    My workaround is:

    // For some reason the views don't draw in the right order unless we give them a little kick. <rdar://11852080>
    id subviewsCache = [[[self stageHolderView1] subviews] copy];
    [[self stageHolderView1] setSubviews:subviewsCache];

    The bug dates from 10.7 and will presumably never be fixed, like most everything in Radar.  Sorry, can't help it. :)

    Cheers,

    --
    ____________________________________________________________
    Sean McBride, B. Eng                <sean...>
    Rogue Research                        www.rogue-research.com
    Mac Software Developer              Montréal, Québec, Canada
  • On Apr 30, 2013, at 08:55 , Mike Abdullah <cocoadev...> wrote:

    > On 30 Apr 2013, at 16:53, Gideon King <gideon...> wrote:
    >
    >> So it sounds as if as long as I have all my views in the entire hierarchy layer backed, my sibling views should always draw in order.
    >
    > Yup. Bear in mind WebViews don't support being layer-backed (still!), which can throw a spanner in the works.

    Nope. I just tried it again, setting the layer-backed checkboxes all the way up in IB, and it still fails sometimes (about 1 time out of every 20 or 30, today).
  • How did you test it? Did you sort the views at all, or just leave them in the order they were instantiated? Did you try Sean's workaround?

    Regards

    Gideon

    On 01/05/2013, at 4:39 AM, Quincey Morris <quinceymorris...> wrote:

    >
    > Nope. I just tried it again, setting the layer-backed checkboxes all the way up in IB, and it still fails sometimes (about 1 time out of every 20 or 30, today).
    >
  • On Apr 30, 2013, at 18:37 , Gideon King <gideon...> wrote:

    > How did you test it? Did you sort the views at all, or just leave them in the order they were instantiated?

    My hierarchy is very simple. The content view contains a single view (which layer-backed in order to use a background color), and that view contains two child views whose order is set in IB. I made no programmatic adjustments to anything. The only change from my original attempt was to make all of the views layer-backed in IB. Both child views are custom views, and they both return NO for "isOpaque".

    I did, however, verify that the order of the child views was correct and hadn't been inadvertently switched somewhere in nib loading. The view order was correct.

    > Did you try Sean's workaround?

    No, but I have no doubt it works as he says.
previous month april 2013 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30          
Go to today