Seal CALayers

I have an NSView that contains a lot of CALayers. When a user edits a document, these CALayers enliven all changes. I am trying to implement printing for my application, but I am having problems printing these CALayers correctly.

Some CALayers' borders occupy the entire NSView and do not need to be planned because their position never changes. However, I also have one CALayer that contains about 20 small CALayers. These CALayers expect changes in their positions during regular editing. However, when you try to print NSView, these small CALayers will never be correctly placed. I am wondering if there is anything special that I have to do to ensure that these layers are placed correctly and allow NSView to draw / print correctly.

Does anyone have experience printing NSView with Core Animation support? Any suggestions are welcome.

+3
source share
2 answers

To get around layout problems, as well as the fact that using -renderInContext:layers to draw hierarchies does not preserve vector elements, we subclassed CALayer into Basic Layout Basics . The CPLayer subclass overrides the default method -drawInContext:to invoke our own method -renderAsVectorInContext:(where we make all our Core Graphics drawings for the layer). To create a PDF context (or similar) for printing, we call a custom method with the following code:

-(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, , . , , , .

+5

, , CALayers. , Core Animation , ( , iPhone).

, .

0

Source: https://habr.com/ru/post/1744163/


All Articles