-renderInContext:
レイアウトの問題や、 を使用してレイヤー階層を描画するとベクター要素が保持されないという事実を回避するために、 Core Plot フレームワークで CALayer をサブクラス化しました。CPLayer サブクラスは、デフォルト-drawInContext:
メソッドをオーバーライドして、カスタム メソッドを呼び出します-renderAsVectorInContext:
(ここで、レイヤーのすべてのコア グラフィックス描画を行います)。印刷用の PDF コンテキスト (または類似のもの) を生成するには、次のコードでカスタム メソッドを呼び出します。
-(void)recursivelyRenderInContext:(CGContextRef)context
{
// render self
CGContextSaveGState(context);
[self applyTransform:self.transform toContext:context];
self.renderingRecursively = YES;
if ( !self.masksToBounds ) {
CGContextSaveGState(context);
}
[self renderAsVectorInContext:context];
if ( !self.masksToBounds ) {
CGContextRestoreGState(context);
}
self.renderingRecursively = NO;
// render sublayers
for ( CALayer *currentSublayer in self.sublayers ) {
CGContextSaveGState(context);
// Shift origin of context to match starting coordinate of sublayer
CGPoint currentSublayerFrameOrigin = currentSublayer.frame.origin;
CGRect currentSublayerBounds = currentSublayer.bounds;
CGContextTranslateCTM(context,
currentSublayerFrameOrigin.x - currentSublayerBounds.origin.x,
currentSublayerFrameOrigin.y - currentSublayerBounds.origin.y);
[self applyTransform:self.sublayerTransform toContext:context];
if ( [currentSublayer isKindOfClass:[CPLayer class]] ) {
[(CPLayer *)currentSublayer recursivelyRenderInContext:context];
} else {
if ( self.masksToBounds ) {
CGContextClipToRect(context, currentSublayer.bounds);
}
[currentSublayer drawInContext:context];
}
CGContextRestoreGState(context);
}
CGContextRestoreGState(context);
}
これにより、各レイヤーがフラットな Core Graphics コンテキストにレンダリングされ、位置、回転、およびその他の変換が維持され、すべての要素がシャープなベクトルとしてレンダリングされます。
レイヤーをレンダリングする際に注意すべきもう 1 つの点は、プレゼンテーション レイヤー階層の状態が内部レイヤー階層と同じではない可能性があることです。レイヤーを移動するために適用されたアニメーションがあるかもしれませんが、レイヤーのposition
プロパティが一致するように変更されていない可能性があります。その場合、値が常に同期されるようにプロパティ自体をアニメーション化するか、アニメーションが完了したらレイヤーに値を設定する必要があります。