2012-05-23 9 views
7

レイヤーホストNSViews(CALayerインスタンスを提供し、setLayer:で設定したNSView)には明らかにサブビューが含まれています。なぜ明らかに?アップル独自のCocoa Slides sample code projectに、あなたはレイヤーホスティングであることに層担保されることからAssetCollectionViewを切り替えチェックボックスをチェックすることができますので:同じAssetCollectionViewクラスでレイヤーホスティングNSViewはサブビューを持つことができますか?

- (void)setUsesQuartzCompositionBackground:(BOOL)flag { 
    if (usesQuartzCompositionBackground != flag) { 
     usesQuartzCompositionBackground = flag; 

     /* We can display a Quartz Composition in a layer-backed view tree by 
      substituting our own QCCompositionLayer in place of the default automanaged 
      layer that AppKit would otherwise create for the view. Eventually, hosting of 
      QCViews in a layer-backed view subtree may be made more automatic, rendering 
      this unnecessary. To minimize visual glitches during the transition, 
      temporarily suspend window updates during the switch, and toggle layer-backed 
      view rendering temporarily off and back on again while we prepare and set the 
      layer. 
     */ 
     [[self window] disableScreenUpdatesUntilFlush]; 
     [self setWantsLayer:NO]; 
     if (usesQuartzCompositionBackground) { 
      QCCompositionLayer *qcLayer = [QCCompositionLayer compositionLayerWithFile:[[NSBundle mainBundle] pathForResource:@"Cells" ofType:@"qtz"]]; 
      [self setLayer:qcLayer]; 
     } else { 
      [self setLayer:nil]; // Discard the QCCompositionLayer we were using, and let AppKit automatically create self's backing layer instead. 
     } 
     [self setWantsLayer:YES]; 
    } 
} 

を、サブビューが表示されるべき各画像のために追加されます。

- (AssetCollectionViewNode *)insertNodeForAssetAtIndex:(NSUInteger)index { 
    Asset *asset = [[[self assetCollection] assets] objectAtIndex:index]; 
    AssetCollectionViewNode *node = [[AssetCollectionViewNode alloc] init]; 
    [node setAsset:asset]; 
    [[self animator] addSubview:[node rootView]]; 
    [nodes addObject:node]; 

    return [node autorelease]; 
} 

私がアプリケーションをビルドして実行して、それを使いこなすと、すべてがうまくいくようです。

しかし、Apple's NSView Class Reference for the setWantsLayer: methodにそれが読み取ります

あなたは 描画用のビューに依存すべきではない層ホスティングビューを使用して、またあなたは、レイヤのホスティングビューにサブビューを追加する必要があります。

本当ですか?サンプルコードが間違っていますか?それはうまくいくのですか?それともドキュメントが偽であるのですか?または、サブビューがアニメータープロキシを介して追加されているのでOKですか?

答えて

19

AppKitが「レイヤーホスティング」のときは、AppKitが知らない層のサブツリー全体があるかもしれないと思うかもしれません。

レイヤーホステッドビューにサブビューを追加すると、適切な兄弟順に表示されないことがあります。さらに、setLayer:、setWantsLayer:を呼び出すとき、またはスーパービューからビューが追加または削除されたときに変更されることがあります。ライオンでは、ウィンドウ(またはスーパービュー)からビューが削除されたときに、自分が所有するレイヤー(レイヤーバック)を削除します。

NSViews以外の兄弟レイヤーを持っている場合、サブビューを追加することはできますが、サブレイヤ配列内の子兄弟順序は決定的ではないかもしれません。

+0

ありがとうとてもとても! –

1

「正しい」答えは何か分かりません。しかし、私は、CocoaSlidesの例は、あなたが「してはいけない」と言っているものの境界内で動作すると考えています。この例では、insertNodeForAssetAtIndex:メソッドが呼び出された場所を見て、ビューがポピュレートされているときにのみ表示されます。より前にはのレイヤーが割り当てられているか、またはsetWantsLayer:が呼び出されています。

ドキュメントでは、レイヤーホストビューにサブビューが含まれていないとは言わず、にはとサブビューを1つ追加することはできません。これらのサブビューが追加された時点で、メインビューはまだレイヤーホストビューにはなっていません。手動で作成されたレイヤーが割り当てられて、レイヤーホスティングビューになった後は、それ以上のサブビューは追加されません。

したがって、ドキュメントとこの特定の例の間には矛盾がありません。つまり、最初からQCバックグラウンドレイヤーを切り替えることで、これをさらに詳しく調べることができます。内に[self setUsesQuartzCompositionBackground:YES];を貼り付けてinitWithFrame:のように貼り付けます。

SPOLIER警告: これはうまくいくようです。ディスプレイの作成は少し遅くなります(品質管理アニメーションはすべて驚くべきことではありません)。しかしそれ以外はスムーズなセーリングです。

+0

ありがとう、ジャック!すでに「サブビュー」を持っていることを「追加」することに関する興味深い観察。おそらく、この質問について書かれているように、ドキュメントは最新ではありません。http://stackoverflow.com/questions/10720062/are-layer-backed-nsview-siblings-allowed-to-overlap/10720422#10720422 –

0

アップルからこのコードについての1コメント:それは逮捕されました。

初めてアプリを起動するときは、すばらしいグラデーションの背景に注意してください。 QCをオンにしてからオフにします。

偽、勾配の背景はありません。

関連する問題