Adding a UILabel's layer to another layer (Sep

2019-07-29 23:13发布

问题:

I'm trying to understand why I can't add a UILabel's layer as a sublayer to another layer in a separate UIView object.

- (void)addNumber:(NSInteger)number toLayer:(CALayer *)layer {

  UILabel *numberLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds))];
  [numberLabel setFont:[UIFont boldSystemFontOfSize:12]];
  [numberLabel setText:[NSString stringWithFormat:@"%d", number]];
  /* if I change the BackgroundColor to an opaque color it renders as a solid black rect.
   * No matter what color I choose
   * Setting it as clear then it is transparent
   */
  [numberLabel setBackgroundColor:[UIColor clearColor]];
  [numberLabel setTextAlignment:NSTextAlignmentCenter];
  [numberLabel setTextColor:[UIColor blackColor]];

  CALayer *numberLayer = numberLabel.layer;

  /* However creating a CATextLayer is successful
  CALayer *numberLayer = [CATextLayer layer];
  [numberLayer setFont:(__bridge CFTypeRef)([UIFont boldSystemFontOfSize:12])];
  [numberLayer setBounds:CGRectMake(0, 0, CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds))];
  [numberLayer setString:[NSString stringWithFormat:@"%d", number]];
  [numberLayer setAlignmentMode:kCAAlignmentCenter];
  [numberLayer setForegroundColor:[[UIColor whiteColor] CGColor]];
  */

  [numberLayer setPosition:CGPointMake(CGRectGetMidX(layer.bounds),
                                        CGRectGetMidY(layer.bounds) + CGRectGetMidY(numberLayer.bounds))];  
  [layer addSublayer:numberLayer];
}

However, if I was to create a CATextLayer instead, it works fine. (see commented out code)

My understanding is that every UIView subclass is backed by a root CALayer. Should I not be able to add that root CALayer to the sublayer hierarchy of another CALayer ?

Thank you for your help

回答1:

numberLayer is a pointer to numberLabel.layer, so it's a single instance - a single instance of a layer or UIView can only be a child to one parent, not multiple.



回答2:

CALayer conforms to NSCoding protocol, so you can encode existing CALayer instance, then create new CALayer instance by decoding data from the first one.

  1. try reading this.
  2. and also this answer as well after the first reference.