Cocoa 印刷炉

Cocoa 印刷炉,cocoa,printing,core-animation,calayer,nsview,Cocoa,Printing,Core Animation,Calayer,Nsview,我有一个包含许多Calayer的NSView。当用户编辑文档时,这些Calayer会设置所有编辑的动画。我正在尝试为我的应用程序实现打印,但我在正确打印这些Calayer时遇到一些问题 一些CALayers边界占据了整个NSView,不需要进行布局,因为它们的位置永远不会改变。然而,我也有一个CALayer,其中包含大约20个小CALayer。这些Calayer在正常编辑期间设置其位置更改的动画。然而,当试图打印NSView时,这些小Calayer永远无法正确布局。我想知道我是否需要做一些特殊的

我有一个包含许多Calayer的NSView。当用户编辑文档时,这些Calayer会设置所有编辑的动画。我正在尝试为我的应用程序实现打印,但我在正确打印这些Calayer时遇到一些问题

一些CALayers边界占据了整个NSView,不需要进行布局,因为它们的位置永远不会改变。然而,我也有一个CALayer,其中包含大约20个小CALayer。这些Calayer在正常编辑期间设置其位置更改的动画。然而,当试图打印NSView时,这些小Calayer永远无法正确布局。我想知道我是否需要做一些特殊的事情来确保这些层的位置正确,并允许正确绘制/打印NSView


有没有人有打印核心动画视图的经验?非常感谢您的建议。

上次我查看时,无法正确打印CALayers。在我看来,当时的核心动画只是为屏幕设计的,而不是为打印设计的(这似乎与它最初为iPhone设计的事实一致)


我很想知道我错了。

为了解决布局问题,以及使用
-renderContext:
绘制图层层次结构不会保留矢量元素这一事实,我们在中对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);
}
这将贯穿每一层并将其渲染到一个平面核心图形上下文上,保留位置、旋转和其他变换,同时将所有元素渲染为锐利向量

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