How does z-ordering work with sibling NSViews in Cocoa? I'm confused because I'm finding conflicting sources of information in Apple's docs and APIs. (Note: Subviews are obviously rendered on top of its parent view, I am talking explicitly about sibling views here).
Hypothesis A: "Yes, you can define the z-order of sibling NSViews
"
- In
IB
you can place views on top of each other and they will always be composited in the way you'd expect. - There's buttons in Xcode under the
Editor
menu named "Send to Back", "Send Forward" etc. - The
NSView
also has a method named- (void)addSubview:(NSView *)aView positioned:(NSWindowOrderingMode)place relativeTo:(NSView *)otherView;
which seems to imply that there is a well defined ordering.
Hypothesis B: "No way, z-order of sibling NSViews
is undefined at runtime. Sometimes it works, sometimes it doesn't. Don't trust it!"
- Apple's Docs (View Programming guide) state:
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.
So which one is it?
Yes, NSView siblings are allowed to overlap, the Apple docs are out of date: Are layer-backed NSView siblings allowed to overlap?
Also, the z-order depends on the order of the subviews in the parent view's
subviews
array.I've been solving the same issue and found that at least on Mavericks it works only with layer backed views. I didn't have chance so far to test it on other OS X versions, but on Mavericks you have to set
wantsLayer
toYES
on all views you want to overlap in order to make it work.