6

Here's my setup: I have a CALAyer to which I want to add sublayers. I create these sublayers by setting upa UILabel and then adding the UILables layer to my main layer. Of course this leaves the heavy UILabel object hovering around in the background. Is it possible to get the layer with all its content from a UIView and get rid of the UIView itself? I already tried this:

UILabel* label;
[...]
[mainLayer addSublayer:[label.layer copy]];
[label release];

But whenever I release the UIView, the content of the layer is also removed. Is this even possible or does the UIView's layer always need the UIView itself to show its content? I thought of the layer as a kind of canvas, to which the UIView paints. I guess I could be wrong with this assumption :)

danronmoon
  • 3,814
  • 5
  • 34
  • 56
Haentz
  • 417
  • 5
  • 16

6 Answers6

4

I can't understand why you wouldn't be able to copy a layer. True a layer is an "integral part" of a UIView. But in the end it is just another object with several properties.

Actually there is a method for CALayer called:

- (id)initWithLayer:(id)layer

But it isn't intended to make a copy of a layer. (You can read Apple's docs for the reasoning why)

CALayer does not conform to NSCopying, so you have two options:

  1. Subclass it and implement "copyWithZone:" (and conform to NSCopying)
  2. Write a method/function that will return a "copy" of a CALayer

Regardless of which way you choose, the question you have to ask is: Which properties of the CALlayer do you want to copy?

Let's say you want to copy just the contents and frame:

CALayer copyLayer = [CALayer layer];

copyLayer.contents = theLayerToBeCopied.contents;
copyLayer.frame = theLayerToBeCopied.frame;

return copyLayer;

You could go through and copy every property of the layer, or just copy the ones you need. Might be a good method to put in a CALayer category.

Corey Floyd
  • 25,929
  • 31
  • 126
  • 154
  • 1
    Perhaps because the purpose of a layer is to render its associated UIView and its sublayers. If the UIView disappears because you release it, then why would you need to use a layer that was originally tied to that UIView? If you really need a layer it appears logical to me that you also need its UIView. Haentz may certainly try the approach you suggested (and I am not sure if it will work), but I have not seen this before in Core Animation code. Also, if Apple thought of making this possible, it would have made CALayer compliant with NSCopying. Please let me know if this approach works or not. – Massimo Cafaro Jun 07 '09 at 15:51
  • The only reason I can see for copying a CALayer is if he needed to display multiples of the same layer on screen. I think usually you would just go about creating the multiple layers the same way you created the first. Although, I don't see why you would make a copy if you intended on destroying the first either. My thinking was that he didn't really need a "copy" as much as he needed a layer with the same properties as the original. You're right as in it probably isn't the accepted solution to the problem, but interesting to see how it works. – Corey Floyd Jun 07 '09 at 16:46
1

UIViews are not that heavy in iOS. For the most part, you can think of them as a supporting wrapper around a CALayer. Unlike on Mac where a NSView doesn't have to be backed by a CALayer, that's not true in iOS. All UIView instances are CALayer-backed and that's where most of the heavy lifting is. Apple's docs even say things like 'Don't bother animating a UIView's layer. Animate the UIView directly as it's essentially just sending it all down to the layer anyway.' (Paraphrased, of course.)

Point being, unless you specifically need UILayer instances for something that's not directly supported by a UIView, just stick with working with UIViews entirely and you should be good to go.

Mark A. Donohoe
  • 28,442
  • 25
  • 137
  • 286
1

It is not possible: a layer is a property of a UIView. Therefore, when you release the UIView, its layer is gone. Your idea of thinking of the layer as a kind of canvas is not wrong. But, the layer is an integral part of its UIView.

Massimo Cafaro
  • 25,429
  • 15
  • 79
  • 93
0

use CAReplicatorLayer, you will be able to completely replicate that layer

ossamacpp
  • 656
  • 5
  • 11
0

You can also circumvent UILabel entirely and create your text with a CATextLayer.

Zev Eisenberg
  • 8,080
  • 5
  • 38
  • 82
0

UILabel really isn't a very complex control. I suggest you give up this line of attack and learn how to draw what you want using Quartz into a fresh CGImage. You can then assign this to the contents property of the CALayer without having to worry about all this other stuff.

U62
  • 4,355
  • 1
  • 24
  • 37