cocoa - 打印CAL层

标签 cocoa printing core-animation calayer nsview

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

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

有人有打印 Core Animation 支持的 NSView 的经验吗?如有任何建议,我们将不胜感激。

最佳答案

为了解决布局问题,以及使用 -renderInContext: 绘制图层层次结构不会保留向量元素这一事实,我们在 Core Plot framework 中对 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);
}

这会遍历每个层并将其渲染到平坦的 Core Graphics 上下文上,保留位置、旋转和其他变换,同时将所有元素渲染为锐向量。

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

关于cocoa - 打印CAL层,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2773753/

相关文章:

从非返回函数打印 Python

qt - 如何在嵌入式 Web 浏览器中支持 window.print()?

ios - 整体加入了UIBezierPath笔画

objective-c - 如何在 NSViewController.transition 期间将 NSViewController 固定到 NSPopover 的顶部?

objective-c - NSTabView 与 NSTabViewController ——何时使用 Controller ?

objective-c - 折叠动画与滑动动画不对齐

ios - 在 iOS 上绘制动态角度(锥形)渐变的最快方法?

Cocoa 文件/目录监视库可用吗?

javascript - 如何在没有打印预览窗口的情况下进行打印

objective-c - 淡入/淡出 UIScrollView 的内容,就像 Mobile Safari 在其选项卡中所做的那样