1

I want to create a PDF from a UIView. Now I want to copy the layer and resize it to a DIN A4 page size.

CGRect A4PageRect = CGRectMake(0, 0, 595, 842);
CALayer *myLayer = [pdfView layer];
myLayer.bounds = pageRect;

But this cody resizes the visible layer on my screen.

How can I copy the layers contents to resize it to fit an A4 page?

Thanks for help, Julian

Julian F. Weinert
  • 7,474
  • 7
  • 59
  • 107

3 Answers3

3

FWIW, you can make a shallow copy of a CALayer via:

(Swift 3)

let tmp = NSKeyedArchiver.archivedData(withRootObject: myLayer)
let copiedCA = NSKeyedUnarchiver.unarchiveObject(with: tmp) as! CALayer

(or whatever subclass you are using. e.g. CAShapeLayer)

Thanks to: https://stackoverflow.com/a/35345819/1452758

Community
  • 1
  • 1
Womble
  • 4,607
  • 2
  • 31
  • 45
2

There is no way to duplicate a CALayer.

(It would be difficult for CoreAnimation to implement that in a sensible way. There might be a whole tree of sublayers, and they all might have delegates that influence their behavior, which wouldn't expect to suddenly get requests from the copies of the layers.)

I can only guess at a better solution, because I don't understand your exact situation. Do you have a PDF that you are trying to resize, or do you just want take an arbitrary existing layer and make a PDF document out of it?

If the latter:

  1. Use UIGraphicsBeginPDFContextToData or UIGraphicsBeginPDFContextToFile to create a PDF drawing context
  2. Call UIGraphicsBeginPDFPage or UIGraphicsBeginPDFPageWithInfo to create a page
  3. Call UIGraphicsGetCurrentContext to get the PDF drawing context
  4. Scale using CGContextScaleCTM so your layer will fit in the PDF page
  5. Call -[CALayer renderInContext:] to draw the layer into the PDF context
  6. Call UIGraphicsEndPDFContext to finish the PDF

Note that this may look terrible. Layers are bitmap-based, so you'll get a bitmap in your PDF. Also, -[CALayer renderInContext:] doesn't render exactly the same as it does on-screen -- see the note in the documentation.

If this is a problem, you'll need to add a separate drawing path that bypasses CALayer. In step 5, you would do your own drawing using CoreGraphics.

Kurt Revis
  • 27,695
  • 5
  • 68
  • 74
0

In your case it's indeed better to go with the proposed solution but for the record, yes you can duplicate - in a way - a CALayer : using CAReplicatorLayer.

It's a very powerful API, not necessary build for duplicating one layer but it works for that too. It works even better for making astonishing visual effects by duplicating series of layers.

For more information you can have a look at the apple official documentation, here an extract:

A layer that creates a specified number of copies of its sublayers (the source layer), each copy potentially having geometric, temporal, and color transformations applied to it.

And here a great tutorial by John Sundell, another extract:

CAReplicatorLayer specializes in drawing multiple copies of an original layer (hence it being a "replicator"), in an efficient - hardware accelerated - manner. It's super useful when drawing things like tiled backgrounds, patterns or other things that should be repeated multiple times. I even use it to implement the texture tiling feature of my upcoming open source Swift game engine.

And finally here a great example of what can be done with this api.

Macistador
  • 854
  • 12
  • 23