【问题标题】:CALayer random ordering in Cocoa (Mac OS)Cocoa 中的 CALayer 随机排序 (Mac OS)
【发布时间】:2013-08-13 04:41:03
【问题描述】:

这个错误快把我逼疯了...每次我从 Xcode 运行我的应用程序时,我的面板都会以随机顺序绘制它的图层!即使子视图顺序完好无损!!

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

我对@9​​87654323@s 做了什么奇怪的事情吗?绝对不是...我在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 = ...
)

【问题讨论】:

    标签: macos cocoa core-animation calayer


    【解决方案1】:

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

    【讨论】:

    • 很高兴补充一下为什么会这样..您是否遇到过这个问题,是否在其他地方提到过,在 XIB 中启用层时是否存在明显的错误,我错过了?
    • 我相信这是 XCode 中的一个错误,也许有一些针对它的雷达,但绝对为我解决了完全相同的问题...
    • 感谢您的澄清,这肯定比我的回答提供更多信息
    【解决方案2】:

    尽管我讨厌这个解决方案,但至少它有效:

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

    代码有时会到达 NSLog 语句,有时不会。不管怎样,最后一行确保frameView(如果你一直关注KMStatusPanelView)的图层位于顶部。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-11
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-22
      • 1970-01-01
      • 2013-01-30
      相关资源
      最近更新 更多