Cocoa(Mac OS)中的CALayer随机排序



这个bug让我抓狂。。。每次我从Xcode运行我的应用程序时,我的面板都会按随机顺序绘制它的图层!即使子视图顺序是完整的!!

该应用程序是一个状态栏应用程序,当用户单击状态项时,它会显示一个简单的NSPanelNSPanel是从笔尖加载的,我不能说我做了更多!!

我对CALayer做了什么奇怪的事吗?绝对不是。。。我在KMStatusPanelView中所拥有的只是一个被覆盖的-[NSView drawRect:]KMRootView具有以下功能:

KMRootVC中,它是KMRootView的视图控制器,我有:

- (void)awakeFromNib
{
    [super awakeFromNib];
    NSAssert(self.view.layer, @"Layer not created");
    [self.view.layer setCornerRadius:18.0];
    [self _loadControllerAtIndex:0];
}

KMRootView中,我覆盖-[NSView drawRect:],并且还具有:

- (void)awakeFromNib
{
    [super awakeFromNib];
    NSAssert(self.layer, @"Layer not found");
    [self.layer setMasksToBounds:YES];
}

就是这样!这就是所有与核心动画层相关的代码,除了我在IB中勾选了复选标记来为我创建层,而不是调用-[NSView setWantsLayer:]

以下是两次不同运行的日志(我已经删除了大部分不相关的数据):
显然,KMRootView应该位于底部,正如您从-[NSView subviews]输出中看到的那样。

以正确的结果运行:

$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 = ...
)

不要在层次结构中的任何位置使用IB来启用层支持视图,而是在awakeFromNib中调用setWantsLayer:YES

尽管我很讨厌这个解决方案,但至少它能工作:

NSView* view = self.contentView;
if (view.layer.sublayers[0] == self.frameView.layer)
{
    NSLog(@"WTF?");
}
[view.layer addSublayer:self.frameView.layer];

代码有时会到达NSLog语句,有时不会。无论哪种方式,最后一行都确保frameView(如果您一直在关注KMStatusPanelView)的层位于顶部。

最新更新