2

このバグは私を夢中にさせています... Xcode からアプリを実行するたびに、パネルはレイヤーをランダムな順序で描画します! サブビューの順序はそのままですが!!

NSPanelこのアプリは、ユーザーがステータス アイテムをクリックするとシンプルなステータス バー アプリを表示するアプリです。はNSPanelペン先からロードされており、それ以上のことはできません!!

私はCALayersで何か変なことをしていますか?絶対にありません...私が持って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];
}

それでおしまい!コア アニメーション レイヤーに関連するコードはこれですべてです。ただし、-[NSView setWantsLayer:].

これは 2 つの異なる実行からのログです (無関係なデータのほとんどを削除しました):出力からわかるように、
明らかに、一番下にあるはずです。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 = ...
)
4

2 に答える 2

1

Don't use IB to enable layer backed views nowhere in hierarchy, but in awakeFromNib call setWantsLayer:YES

于 2016-04-29T18:46:50.587 に答える
0

私はこのソリューションが嫌いですが、少なくとも機能します:

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

コードは NSLog ステートメントに到達する場合と到達しない場合があります。いずれにせよ、最後の行により、frameView(KMStatusPanelViewフォローしている場合) のレイヤーが一番上にあることが保証されます。

于 2013-08-13T04:58:09.520 に答える