Display UIView with a UILabel text mask

I’m trying to add a UIView to a UILabel, so that the text is the view’s mask, enabling me to do things like animated text backgrounds (much like the slide to unlock label on the lockscreen).

The way I was planning on doing it was using the mask property on the view’s layer to mask it to the shape of the text. However, I cannot find a way to get the UILabel‘s text shape as a CALayer.

  • Make iOS blocks execute synchronously
  • Pass an argument to selector
  • Localizing the Cut|Copy|Paste menu on iOS
  • UICollectionView align logic missing in horizontal paging scrollview
  • Set CALayer as SCNMaterial's diffuse contents
  • Can I use a UIBarButtonSystemItem for a UIButton?
  • Is this even possible? I can only find solutions that override the -(void)drawRect: method in the UILabel, but this wouldn’t give me much flexibility.

    2 Solutions Collect From Internet About “Display UIView with a UILabel text mask”

    UIView added the maskView property in iOS 8.0. Now, just create a UILabel to use as a mask for a UIView:

    Objective-C:

    UILabel* label = [[UILabel alloc] initWithFrame:self.view.frame];
    label.text = @"Label Text";
    label.font = [UIFont systemFontOfSize:70];
    label.textAlignment = NSTextAlignmentCenter;
    label.textColor = [UIColor whiteColor];
    
    UIView* overlayView = [[UIView alloc] initWithFrame:self.view.frame];
    overlayView.backgroundColor = [UIColor blueColor];
    overlayView.maskView = label;
    [self.view addSubview:overlayView];
    

    Swift 2:

    let label = UILabel.init(frame: view.frame)
    label.text = "Label Text"
    label.font = UIFont.systemFontOfSize(70)
    label.textAlignment = .Center
    label.textColor = UIColor.whiteColor()
    
    let overlayView = UIView.init(frame: view.frame)
    overlayView.backgroundColor = UIColor.blueColor()
    overlayView.maskView = label
    
    view.addSubview(overlayView)
    

    This creates a crisp UILabel with UIColor.blueColor() color taken from overlayView.

    mopsled’s solution is more flexible if you building for iOS 8+. However, if you’re looking for a pre-iOS 8 answer, here it is.


    Thanks to Linuxios for pointing me to this question. The key is to use CATextLayer instead of UILabel.

    Objective-C:

    CGRect textRect = {0, 100, self.view.frame.size.width, 100}; // rect to display the view in
    
    CATextLayer* textMask = [CATextLayer layer];
    textMask.contentsScale = [UIScreen mainScreen].scale; // sets the layer's scale to the main screen scale
    textMask.frame = (CGRect){CGPointZero, textRect.size};
    textMask.foregroundColor = [UIColor whiteColor].CGColor; // an opaque color so that the mask covers the text
    textMask.string = @"Text Mask"; // your text here
    textMask.font = (__bridge CFTypeRef _Nullable)([UIFont systemFontOfSize:30]); // your font here
    textMask.alignmentMode = kCAAlignmentCenter; // centered text
    
    UIView* view = [[UIView alloc] initWithFrame:textRect];
    view.backgroundColor = [UIColor blueColor];
    view.layer.mask = textMask; // mask the view to the textMask
    [self.view addSubview:view];
    

    Swift:

    let textRect = CGRect(x: 0, y: 100, width: view.frame.size.width, height: 100) // rect to display the view in
    
    let textMask = CATextLayer()
    textMask.contentsScale = UIScreen.mainScreen().scale // sets the layer's scale to the main screen scale
    textMask.frame = CGRect(origin: CGPointZero, size: textRect.size)
    textMask.foregroundColor = UIColor.whiteColor().CGColor // an opaque color so that the mask covers the text
    textMask.string = "Text Mask" // your text here
    textMask.font = UIFont.systemFontOfSize(30) // your font here
    textMask.alignmentMode = kCAAlignmentCenter // centered text
    
    let bgView = UIView(frame: textRect)
    bgView.backgroundColor = UIColor.blueColor()
    bgView.layer.mask = textMask // mask the view to the textMask
    view.addSubview(bgView)