Apple Developer Connection
Member Login Log In | Not a Member? Contact ADC

< 前ページ次ページ > 目次を隠す

レイヤコンテンツの指定

目次:

CALayerコンテンツの指定
レイヤ内のコンテンツの位置決め


CALayerコンテンツの指定

Cocoaビューを使って何かを表示するときには、NSViewをサブクラス化し、drawRect:を実装する必要があります。しかし多くの場合は、サブクラスを作成する必要はなく、CALayerインスタンスを直接使うことができます。CALayerはキー値コーディングに準拠したコンテナです。つまり、サブクラス化せずにインスタンスに任意の値を格納でき、これにより多くの場合サブクラス化を避けることができます。

CALayerインスタンスのコンテンツは、次のいずれかの方法で指定します。

コンテンツプロパティの設定

レイヤのコンテンツイメージは、CGImageRefへのcontentsプロパティによって指定されます。これは、レイヤの作成時(レイヤのコンテンツプロパティの設定参照)やそれ以外の場合に別のオブジェクトから行うことができます。

リスト 4  レイヤのコンテンツプロパティの設定

CALayer *theLayer;
 
// レイヤを作成し、境界矩形と位置を作成する
theLayer=[CALayer layer];
theLayer.position=CGPointMake(50.0f,50.0f)
theLayer.bounds=CGRectMake(0.0f,0.0f,100.0f,100.0f);
 
// コンテンツプロパティを、theImage(別の場所でロードされている)
// によって指定されたCGImageRefに設定する。
theLayer.contents=theImage;

デリゲートを使ったコンテンツの指定

displayLayer:メソッドまたはdrawLayer:inContext:メソッドを実装するデリゲートクラスを作成し、レイヤコンテンツイメージを設定することで、レイヤのコンテンツの描画や、より優れたカプレセル化を行うことができます。

displayLayer:メソッドを実装するデリゲートは、指定されたレイヤに対してどのイメージが表示されるべきかを決定し、それに応じてレイヤのcontentsプロパティを設定できます。displayLayer:の実装例に示すdisplayLayer:の実装例では、stateキーの値に応じてtheLayercontentsプロパティを設定しています。CALayerインスタンスがキー値コーディングコンテナとして機能するため、state値を格納するためにサブクラス化する必要はありません。

リスト 5  デリゲートメソッドdisplayLayer:の実装例

 
- (void)displayLayer:(CALayer *)theLayer
{
    // レイヤのstateキーの値をチェック
    if ([[theLayer valueForKey:@"state"] boolValue])
    {
        // yesのイメージを表示
        theLayer.contents=[someHelperObject loadStateYesImage];
    }
    else {
        // noのイメージを表示
        theLayer.contents=[someHelperObject loadStateNoImage];
    }
}

レイヤのコンテンツをイメージからロードせずに描画する場合は、drawLayer:inContext:デリゲートメソッドを実装します。デリゲートには、コンテンツを必要としているレイヤと、コンテンツの描画先となるCGContextRefが渡されます。

デリゲートメソッドdrawLayer:inContext:の実装例に示すdrawLayer:inContext::の実装例では、theLayerによって返されたlineWidthキーとlineColorキーの値を描画します。

リスト 6  デリゲートメソッドdrawLayer:inContext:の実装例

 
- (void)drawLayer:(CALayer *)theLayer
        inContext:(CGContextRef)theContext
{
    CGMutablePathRef thePath = CGPathCreateMutable();
 
    CGPathMoveToPoint(thePath,NULL,15.0f,15.f);
    CGPathAddCurveToPoint(thePath,
                          NULL,
                          15.f,250.0f,
                          295.0f,250.0f,
                          295.0f,15.0f);
 
    CGContextBeginPath(theContext);
    CGContextAddPath(theContext, thePath );
 
    CGContextSetLineWidth(theContext,
                          [theLayer valueForKey:@"lineWidth"]);
    CGContextSetStrokeColorWithColor(theContext,
                                     [theLayer valueForKey:@"lineColor"]);
    CGContextStrokePath(theContext);
 
    // パスを解放
    CFRelease(thePath);
}

サブクラス化によるCALayerコンテンツの指定

多くの場合は不要ですが、CALayerをサブクラス化し、描画メソッドと表示メソッドを直接オーバーライドすることができます。これは通常、デリゲートを通じては提供できないようなカスタムの動作がレイヤに要求される場合に行います。

サブクラス化により、CALayer表示メソッドをオーバーライドし、レイヤのコンテンツに適切なイメージを設定できます。CALayer表示メソッドのオーバーライドの例に示す例は、デリゲートメソッドdisplayLayer:の実装例に示したdisplayLayer:のデリゲートの実装と同じ機能を提供します。違いは、サブクラスではCALayerのキー値コーディングコンテナ機能に依存するのではなく、stateをインスタンスプロパティとして定義する点です。

リスト 7  CALayer表示メソッドのオーバーライドの例

 
- (void)display
{
    // レイヤのstateキーの値をチェック
    if (self.state)
    {
        // yesのイメージを表示
        self.contents=[someHelperObject loadStateYesImage];
    }
    else {
        // noのイメージを表示
        self.contents=[someHelperObject loadStateNoImage];
    }
}

CALayerサブクラスは、drawInContext:をオーバーライドすることにより、レイヤのコンテンツをグラフィックスコンテキストに描画できます。CALayer drawInContext:メソッドのオーバーライドの例に示す例では、デリゲートメソッドdrawLayer:inContext:の実装例に示したデリゲートの実装と同じコンテンツイメージを生成します。この場合も、実装の唯一の違いはサブクラスのインスタンスプロパティとして、lineWidthlineColorが宣言される点です。

リスト 8  CALayer drawInContext:メソッドのオーバーライドの例

 
- (void)drawInContext:(CGContextRef)theContext
{
    CGMutablePathRef thePath = CGPathCreateMutable();
 
    CGPathMoveToPoint(thePath,NULL,15.0f,15.f);
    CGPathAddCurveToPoint(thePath,
                          NULL,
                          15.f,250.0f,
                          295.0f,250.0f,
                          295.0f,15.0f);
 
    CGContextBeginPath(theContext);
    CGContextAddPath(theContext, thePath );
 
    CGContextSetLineWidth(theContext,
                          self.lineWidth);
    CGContextSetStrokeColorWithColor(theContext,
                                     self.lineColor);
    CGContextStrokePath(theContext);
    CFRelease(thePath);
}

レイヤ内のコンテンツの位置決め

CALayerのプロパティcontentsGravityにより、レイヤの境界内におけるレイヤのcontentsイメージの位置と縮尺を指定できます。デフォルトでは、コンテンツイメージはレイヤの境界矩形全体に塗りつぶされ、そのイメージに適したアスペクト比は無視されます。

contentsGravity位置決め定数を使って、イメージをレイヤの端に沿って配置するか、レイヤの角に合わせて配置するか、レイヤの境界矩形内の中心に配置するかを指定できます。レイヤのcontentsGravityプロパティに対する位置決め定数に、位置決め定数とそれに対応する位置の一覧を示します。

表 7  レイヤのcontentsGravityプロパティに対する位置決め定数

位置決め定数

説明

kCAGravityTopLeft

コンテンツイメージをレイヤの左上角に配置します。

kCAGravityTop

コンテンツイメージを、レイヤの上端に沿って水平方向の中央に配置します。

kCAGravityTopRight

コンテンツイメージをレイヤの右上角に配置します。

kCAGravityLeft

コンテンツイメージを、レイヤの左端に沿って垂直方向の中央に配置します。

kCAGravityCenter

コンテンツイメージをレイヤの中央に配置します。

kCAGravityRight

コンテンツイメージを、レイヤの右端に沿って垂直方向の中央に配置します。

kCAGravityBottomLeft

コンテンツイメージをレイヤの左下角に配置します。

kCAGravityBottom

コンテンツイメージを、レイヤの下端に沿って中央に配置します。

kCAGravityBottomRight

コンテンツイメージをレイヤの右下角に配置します。

「レイヤのcontentsGravityプロパティの位置決め定数」に、サポートされているコンテンツ位置とそれに対応する定数を示します。


図 9  レイヤのcontentsGravityプロパティに対する位置決め定数

Position constants for a layer’s contentsGravity property

contentsGravityプロパティをレイヤのcontentsGravityプロパティの拡大縮小定数に示す定数の1つに設定することによって、コンテンツイメージを拡大縮小できます。

表 8  レイヤのcontentsGravityプロパティに対する拡大縮小定数

拡大縮小定数

説明

kCAGravityResize

コンテンツイメージを、レイヤの境界矩形全体を完全に塗りつぶすようにサイズ変更します。コンテンツに適したアスペクト比は無視される可能性があります。これはデフォルトで適用されます。

kCAGravityResizeAspect

コンテンツイメージを、アスペクト比を維持しながらレイヤの境界矩形内にできるだけ大きなサイズで表示されるように拡大縮小します。

「レイヤのcontentsGravityプロパティに対する拡大縮小定数」は、サイズ変更モードを使うことによって、正方形のイメージが矩形のレイヤの境界内にどのように埋められるかを示しています。


図 10  レイヤのcontentsGravityプロパティに対する拡大縮小定数

Scaling constants for a layer’s contentsGravity property



< 前ページ次ページ > 目次を隠す


Last updated: 2007-12-06




Did this document help you?
Yes: Tell us what works for you.

It’s good, but: Report typos, inaccuracies, and so forth.

It wasn’t helpful: Tell us what would have helped.
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Copyright © 2007 Apple Inc.
All rights reserved. | Terms of use | Privacy Notice