3

多くの CALayers を含む NSView があります。ユーザーがドキュメントを編集しているとき、これらの CALayer はすべての編集をアニメーション化します。アプリに印刷を実装しようとしていますが、これらの CALayers を正しく印刷する際に問題が発生しています。

一部の CALayers 境界は NSView 全体を占有し、その位置が変更されないため、配置する必要はありません。ただし、約 20 個の小さな CALayer を含む CALayer も 1 つあります。これらの CALayer は、通常の編集中に位置の変化をアニメートします。ただし、NSView を印刷しようとすると、これらの小さな CALayer が正しくレイアウトされません。これらのレイヤーが正しく配置されていることを確認し、NSView を正しく描画/印刷できるようにするために何か特別なことをしなければならないかどうか疑問に思っています。

Core Animation でサポートされた 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 コンテキストにレンダリングされ、位置、回転、およびその他の変換が維持され、すべての要素がシャープなベクトルとしてレンダリングされます。

レイヤーをレンダリングする際に注意すべきもう 1 つの点は、プレゼンテーション レイヤー階層の状態が内部レイヤー階層と同じではない可能性があることです。レイヤーを移動するために適用されたアニメーションがあるかもしれませんが、レイヤーのpositionプロパティが一致するように変更されていない可能性があります。その場合、値が常に同期されるようにプロパティ自体をアニメーション化するか、アニメーションが完了したらレイヤーに値を設定する必要があります。

于 2010-05-07T19:51:39.923 に答える
0

最後に調べたところ、CALayers を正しく印刷できませんでした。当時、Core Animation は印刷用ではなくスクリーン用に設計されているように思えました (これは、当初 iPhone 用に設計されたという事実と一致しているようです)。

私が間違っていることを知りたいです。

于 2010-05-05T20:48:48.047 に答える