5/15/2010

CALayer setting in initWithFrame:

I try to make custom view that is high performance and animatable. I set layer in custom view's initialize method initWithFrame:

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
  CALayer *layer = [CALayer layer];
  CGColorRef color = CGColorCreateGenericGray(0.0, 1.0);
  layer.backgroundColor = color;
  CGColorRelease(color);
  [self setLayer:layer];
  [self setWantsLayer:YES];
  }
    return self;
}

but, layer doesn't see why.
In some CALayer's sample codes, layer setting is done in awakeFromNib.

- (void)awakeFromNib {
    NSLog(@"%d", [self wantsLayer]);
    NSLog(@"%@", [[self layer] description]);
}

I check as above, layer is exist but wantsLayer method return NO.
Layer now appears that properly implemented as follows.

- (void)awakeFromNib {
    [self setWantsLayer:YES];
}

When custom view is made from code, not nib, awakeFromNib method doesn't call but setWantsLayer: work properly. I looked for document about timing of setWantsLayer: to NSView but could not find. Anyone know?


CALayer を使って高速かつアニメーション可能なカスタムビューを作ろうと思って、カスタムビューの初期化メソッド initWithFrame: でレイヤーを設定してみた。

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
  CALayer *layer = [CALayer layer];
  CGColorRef color = CGColorCreateGenericGray(0.01.0);
  layer.backgroundColor = color;
  CGColorRelease(color);
  [self setLayer:layer];
  [self setWantsLayer:YES];
  }
    return self;
}

でもこれだとなぜかレイヤーが表示されない。
CALayer のサンプルコードを見るとレイヤーの設定は awakeFromNib 内で行われていた。

- (void)awakeFromNib {
    NSLog(@"%d", [self wantsLayer]);
    NSLog(@"%@", [[self layerdescription]);
}

として確認してみると、レイヤーは設定されているが wantsLayer が NO を返しているようだ。
以下のように実装することでちゃんとレイヤーが表示されるようになった。

- (void)awakeFromNib {
    [self setWantsLayer:YES];
}

カスタムビューが nib でなくてコードから生成される場合には awakeFromNib は呼ばれないが setWantsLayer: は正しく効く。この NSView への setWantsLayer: のタイミングについてドキュメントを探しけど見つけられなかった。正しい解答が得られないまま使うのは気持ち悪いけどとりあえず。