This bug is driving me crazy... Each time I run my app from Xcode, my panel draws it's layers in a random order! Even though the subviews order is intact!!
The app is a status bar app, that displays a simple NSPanel
when the user clicks the status item. The NSPanel
is loaded from the nib, and I can't say I do any more than that!!
Am I doing anything weird with the CALayer
s? Absolutely not... All I have in KMStatusPanelView
is an overriden -[NSView drawRect:]
. The KMRootView
has the following:
In KMRootVC
, which is the view controller of KMRootView
, I have:
- (void)awakeFromNib
{
[super awakeFromNib];
NSAssert(self.view.layer, @"Layer not created");
[self.view.layer setCornerRadius:18.0];
[self _loadControllerAtIndex:0];
}
.. and in KMRootView
, I override -[NSView drawRect:]
, and also have:
- (void)awakeFromNib
{
[super awakeFromNib];
NSAssert(self.layer, @"Layer not found");
[self.layer setMasksToBounds:YES];
}
That's it! That's all the code related to the Core Animation layer, with the exception of the fact that I ticked the checkmarks in IB to create the layers for me, instead of calling -[NSView setWantsLayer:]
.
Here is a log from two different runs (I have removed most of the irrelevant data):
Obviously, KMRootView
should be at the bottom, as you can see from the -[NSView subviews]
output.
$2 = 0x000000010029b260 <__NSArrayM 0x10029b260>(
<KMRootView: 0x10029c400>,
<KMStatusPanelView: 0x100248a30>
)
(lldb) po [[[self.window contentView] layer] sublayers]
$3 = 0x0000000100264e50 <CALayerArray 0x100264e50>(
<_NSViewBackingLayer:...; bounds = CGRect (0 0; 320 480); delegate = <KMRootView: 0x10029c400>; sublayers =...,
<_NSViewBackingLayer:...; bounds = CGRect (0 0; 320 488); delegate = <KMStatusPanelView: 0x100248a30>;...
)
$0 = 0x000000010023aa40 <__NSArrayM 0x10023aa40>(
<KMRootView: 0x102430f70>,
<KMStatusPanelView: 0x102430660>
)
(lldb) po [[[self.window contentView] layer] sublayers]
$1 = 0x000000010242d2c0 <CALayerArray 0x10242d2c0>(
<_NSViewBackingLayer:...; bounds = CGRect (0 0; 320 488); delegate = <KMStatusPanelView: 0x102430660>;...,
<_NSViewBackingLayer:...; bounds = CGRect (0 0; 320 480); delegate = <KMRootView: 0x102430f70>; sublayers = ...
)
Don't use IB to enable layer backed views nowhere in hierarchy, but in awakeFromNib
call setWantsLayer:YES