为了解决布局问题,以及使用-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 上下文中,保留位置、旋转和其他变换,同时将所有元素渲染为清晰的向量。
尝试渲染层时要注意的另一件事是表示层层次结构的状态可能与内部层层次结构不同。您可能已经应用了动画来移动图层,但图层的position
属性可能没有更改为匹配。在这种情况下,您应该确保对属性本身进行动画处理,以便值始终保持同步,或者在动画完成后在图层中设置值。