打印CALayers

CJ.*_*CJ. 3 printing cocoa core-animation calayer nsview

我有一个包含许多CALayers的NSView.当用户编辑文档时,这些CALayers会对所有编辑进行动画处理.我正在尝试为我的应用程序实现打印,但是我在正确打印这些CALayers时遇到了一些问题.

一些CALayers边界占据整个NSView,并且不需要布局,因为它们的位置永远不会改变.但是,我还有一个CALayer,其中包含大约20个小型CALayer.这些CALayers在正常编辑期间为其位置更改设置动画.但是,在尝试打印NSView时,这些小型CALayers永远不会正确布局.我想知道是否有一些特殊的事情我必须做,以确保正确定位这些图层,并允许正确绘制/打印NSView.

有没有人有打印Core Animation支持的NSView的经验?任何建议表示赞赏.

Bra*_*son 5

为了解决布局问题,以及使用-renderInContext:绘制图层层次结构不保留向量元素的事实,我们在Core Plot框架中继承了CALayer .CPLayer子类重写默认-drawInContext:方法以调用我们的自定义-renderAsVectorInContext:方法(我们为图层执行所有Core Graphics绘图).要生成用于打印的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);
}
Run Code Online (Sandbox Code Playgroud)

这将通过并将每个图层渲染到平面Core Graphics上下文中,保留位置,旋转和其他变换,同时将所有元素渲染为锐利矢量.

尝试渲染图层时要注意的另一件事是表示层层次结构的状态可能与内部图层层次结构不同.您可能拥有已应用于移动图层的动画,但图层的position属性可能尚未更改为匹配.在这种情况下,您应该确保为属性设置动画,以便值始终保持同步,或者在动画完成后设置图层中的值.