Search code examples
cocoa-touchipaduiscrollviewquartz-graphicscalayer

CALayer and Off-Screen Rendering


I have a Paging UIScrollView with a contentSize large enough to hold a number of small UIScrollViews for zooming, The viewForZoomingInScrollView is a viewController that holds a CALayer for drawing a PDF page onto. This allows me to navigate through a PDF much like the ibooks PDF reader.

The code that draws the PDF (Tiled Layers) is located in:

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;

And simply adding a 'page' to the visible screen calls this method automatically. When I change page there is some delay before all the tiles are drawn, even though the object (page) has already been created.

What i want to be able to do is render the next page before the user scrolls to it, thus preventing the visible tiling effect. However, i have found that if the layer is located offscreen adding it to the scrollview doesn't call the drawLayer.

Any Ideas/common gotchas here?

I have tried:

[viewController.view.layer setNeedsLayout]; 
[viewController.view.layer setNeedsDisplay];

NB: The fact that this is replicating the ibooks functionally is irrelevant within the context of the full app.


Solution

  • As i mentioned above, CALayers don't render if they are offscreen.

    I ended up not drawing the PDF directly to the layer but instead, rendered the PDF page to an image when i needed (renders 1 page plus and minus one of the focused page)

    Here is the render code:

    -(UIImage *)renderPDFPageToImage:(int)pageNumber//NSOPERATION?
    {
     //you may not want to permanently (app life) retain doc ref
    
     CGSize size = CGSizeMake(x,y);     
     UIGraphicsBeginImageContext(size);
     CGContextRef context = UIGraphicsGetCurrentContext();
    
     CGContextTranslateCTM(context, 0, 750);
     CGContextScaleCTM(context, 1.0, -1.0);
    
     CGPDFPageRef page;  //Move to class member 
    
        page = CGPDFDocumentGetPage (myDocumentRef, pageNumber);
        CGContextDrawPDFPage (context, page);
    
     UIImage * pdfImage = UIGraphicsGetImageFromCurrentImageContext();//autoreleased
     UIGraphicsEndImageContext();
     return pdfImage;
    
    }