あなたの推測は正しいです。これは実際に描画を最適化するための優れた方法です。要素が上に移動したときに再描画を避けたい大きな静的背景がいくつかあった場合、私は自分でそれを行いました。
CALayer
ビュー内のコンテンツ アイテムごとにオブジェクトを追加するだけです。レイヤーを描画するには、ビューを各レイヤーのデリゲートとして設定してから、drawLayer:inContext:
メソッドを実装する必要があります。
そのメソッドでは、各レイヤーのコンテンツを描画するだけです:
- (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)ctx
{
if(layer == yourBackgroundLayer)
{
//draw your background content in the context
//you can either use Quartz drawing directly in the CGContextRef,
//or if you want to use the Cocoa drawing objects you can do this:
NSGraphicsContext* drawingContext = [NSGraphicsContext graphicsContextWithGraphicsPort:ctx flipped:YES];
NSGraphicsContext* previousContext = [NSGraphicsContext currentContext];
[NSGraphicsContext setCurrentContext:drawingContext];
[NSGraphicsContext saveGraphicsState];
//draw some stuff with NSBezierPath etc
[NSGraphicsContext restoreGraphicsState];
[NSGraphicsContext setCurrentContext:previousContext];
}
else if (layer == someOtherLayer)
{
//draw other layer
}
//etc etc
}
いずれかのレイヤーのコンテンツを更新したい場合は、 を呼び出すだけ[yourLayer setNeedsDisplay]
です。次に、上記のデリゲート メソッドを呼び出して、レイヤーの更新されたコンテンツを提供します。
デフォルトでは、レイヤー コンテンツを変更すると、コア アニメーションは新しいコンテンツに優れたフェード トランジションを提供することに注意してください。ただし、描画を自分で処理している場合、おそらくこれは望ましくないため、レイヤーのコンテンツが変更されたときにアニメーションでデフォルトのフェードが発生するのを防ぐために、actionForLayer:forKey:
デリゲート メソッドを実装し、null を返すことでアニメーションを防止する必要があります。アクション:
- (id<CAAction>)actionForLayer:(CALayer*)layer forKey:(NSString*)key
{
if(layer == someLayer)
{
//we don't want to animate new content in and out
if([key isEqualToString:@"contents"])
{
return (id<CAAction>)[NSNull null];
}
}
//the default action for everything else
return nil;
}