3

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

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

有没有人有打印核心动画支持的 NSView 的经验?任何建议表示赞赏。

4

2 回答 2

5

为了解决布局问题,以及使用-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属性可能没有更改为匹配。在这种情况下,您应该确保对属性本身进行动画处理,以便值始终保持同步,或者在动画完成后在图层中设置值。

于 2010-05-07T19:51:39.923 回答
0

最后我调查了一下,无法正确打印 CALayers。当时在我看来,Core Animation 只是为屏幕设计而不是为打印而设计的(这似乎与它最初是为 iPhone 设计的事实一致)。

我很想知道我错了。

于 2010-05-05T20:48:48.047 回答