Arcadian
Arcadian

Reputation: 4350

How to mask a UILabel in iOS - Objective-C

I want to sub-class a UIView and place four UILabels over top one another ; top label will be the MASK, 2nd label will be a normal label with text, the 3rd label is a label with solid background with no text. the bottom label will the same as the top 2nd label with a different color font. when i sent the width of the third label it will cover up the bottom label showing a partial view of the text. I want to have the 2nd text be one color while the uncoverd bottom label display another color font.

Is this possibe? If someone can explain how to mask in objective-C that will help too.

I trying to build a UIView that acts like a progress bar, as the bar fill to 60%, I want to top text to show in white font color, when the bottom text shows in a different color.

Upvotes: 1

Views: 5164

Answers (2)

Tony
Tony

Reputation: 3478

Rather than using four UILabels, why not subclass UILabel and draw it yourself in the drawRect: method? It would look something like:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();

    // Set the mask
    CGContextClipToMask(context, self.bounds, /* mask image */);

    // Draw the text in a different font
    [self.text drawInRect:rect withFont:/* alternate font */];

    // Draw a solid background
    CGContextSetRGBFillColor(context, ...);
    CGContextFillRect(context, rect);

    // Draw the text normally
    [super drawRect:rect];
}

You could make the masking image and the alternate font properties of your subclass, for convenience.

Upvotes: 0

Daniel Dickison
Daniel Dickison

Reputation: 21882

You could do it with two UILabels, one on the bottom, and one embedded in another view on top.

UILabel *bottomLabel = ...;
[self.view addSubview:bottomLabel];

UIView *topContainer = [[UIView alloc] initWithFrame:bottomLabel.frame];
topContainer.clipsToBounds = YES;
topContainer.opaque = NO;
topContainer.backgroundColor = [UIColor clearColor];

UILabel *topLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, bottomLabel.frame.size.width, bottomLabel.frame.size.height)];
topLabel.text = bottomLabel.text;
topLabel.opaque = NO;
topLabel.backgroundColor = [UIColor clearColor];

[topContainer addSubview:topLabel];
[self.view addSubview:topContainer];

Then, when you want to change the progress, you'd set the width of topContainer. This should clip topLabel.

Upvotes: 2

Related Questions