UILabel adds CAGradientLayer processing flow chart

Why can CAGradientLayer be implemented as background for text containing Chinese

As shown, if the text of UILabel is Chinese, a _UILabelContentLayer is added to draw this text on this layer. It is inserted at the first of uilabel.layer. sublayers.

This time, if we put the CAGradientLayer zPosition set to a negative value, the default CALayer. ZPosition = 0, at the time of rendering, will render the gradient layer first, then apply colours to a drawing the text layer. This serves the purpose of using a gradient as the background.

2. Why not implement CAGradientLayer as background without Chinese text

If the text does not contain Chinese, the system draws the text at the Uilabel.layer (_UILabelLayer) layer. This layer is the parent layer of the CAGradientLayer and will be rendered prior to the CAGradientLayer layer anyway. Therefore, the CAGradientLayer layer renders the text and fails the purpose.

IOS 14+ contains Chinese text, why can’t implement CAGradientLayer as background

In iOS14+, apple optimized it so that it doesn’t add the _UILabelContentLayer, even if the text contains Chinese, and draws directly on the _UILabelLayer layer. Therefore, it is no longer possible to implement a CAGradientLayer as the background.

Iv. Solutions

The CAGradientLayer can only be placed above the superview of UILabel to achieve a gradient background.

5. Experiment code

#import "ViewController.h"

@interface ViewController(a)

@property (nonatomic.strong) UILabel *label;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(100.100.100.100)];
    self.label = label;
    [self.view addSubview:self.label];
    
    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
    gradientLayer.frame = label.bounds;
    gradientLayer.colors = @[(__bridge id) [UIColor redColor].CGColor, (__bridge id) [[UIColor redColor] colorWithAlphaComponent:0.8].CGColor];
    gradientLayer.locations = @[@0The @1.0];
    gradientLayer.startPoint = CGPointMake(0.0);
    gradientLayer.endPoint = CGPointMake(0.1);
    
    [label.layer insertSublayer:gradientLayer atIndex:0];
    
    label.text = Aaaaaaa @ "Chinese";
// label.text = @"aaaaaaaa";
    
    gradientLayer.zPosition = - 10;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@ "% @".self.label.layer);
    NSLog(@ "% @".self.label.layer.sublayers);
}

@end
Copy the code

You can modify the text type, zPosition value, and verify the content in the article. Since the _UILabelContentLayer is not created after the text is set, it is created when the text is drawn. So you have the on-screen click event, UILabel display, click on the screen and output the layer here.