Day 6:RSMaskedLabel,给UILabel添加光罩或镂空效果

先上Github地址:https://github.com/robinsenior/RSMaskedLabel

再来看下运行效果:

RSMaskedLabel

代码介绍:

首先在MaskedLabelViewController中主要对maskedLabel的相关属性进行初始化,例如设置字体、设置居中方式、设置圆角、设置文字、设置背景颜色等。

关键代码在于RSMaskedLabel.h/ .m 中,继承于UILabel,并重写了UILabel的backgroundColor、setBackgroundColor:(UIColor *)backgroundColor、setTextColor:(UIColor *)textColor和drawRect:(CGRect)rect方法。

而在initWithFrame和initWithCoder 两个初始化方法中,均调用了RS_commonInit进行初始化。

RS_commonInit方法中都做了什么呢?

- (void)RS_commonInit
{
    //获取背景颜色
	maskedBackgroundColor = [super backgroundColor];
    //调用父类设置文本颜色
    [super setTextColor:[UIColor whiteColor]];
    //调用父类设置背景颜色为透明
    [super setBackgroundColor:[UIColor clearColor]];
    //设置为不透明
    [self setOpaque:NO];
}

为什么要调用super来设置文本颜色和背景颜色呢,因为我们已经重写了这两个方法,其中设置文本颜色中什么也不做,设置背景颜色中会进行重绘。

这时会调用核心代码drawRect进行绘制。

//核心代码
- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    // let the superclass draw the label normally
    [super drawRect:rect];
    
    
    //
    CGContextConcatCTM(context, CGAffineTransformMake(1, 0, 0, -1, 0, CGRectGetHeight(rect)));
    
    // create a mask from the normally rendered text
    CGImageRef image = CGBitmapContextCreateImage(context);
    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(image), CGImageGetHeight(image), CGImageGetBitsPerComponent(image), CGImageGetBitsPerPixel(image), CGImageGetBytesPerRow(image), CGImageGetDataProvider(image), CGImageGetDecode(image), CGImageGetShouldInterpolate(image));
    
    CFRelease(image); image = NULL;
    
    // wipe the slate clean
    CGContextClearRect(context, rect);
    
    CGContextSaveGState(context);
    CGContextClipToMask(context, rect, mask);

	if (self.layer.cornerRadius != 0.0f) {
		CGContextAddPath(context, CGPathCreateWithRoundedRect(rect, self.layer.cornerRadius, self.layer.cornerRadius, nil));
		CGContextClip(context);
	}

    CFRelease(mask);  mask = NULL;
    
    [self RS_drawBackgroundInRect:rect];
    
    CGContextRestoreGState(context);
    
}

- (void) RS_drawBackgroundInRect:(CGRect)rect
{
    // this is where you do whatever fancy drawing you want to do!
    CGContextRef context = UIGraphicsGetCurrentContext();
    
	[maskedBackgroundColor set];
    CGContextFillRect(context, rect);
}

 

大家可以学到的知识点:

1、自定义UILabel。

2、drawRect自定义绘制。

 

 

本文来自Awnlab.com麦芒实验室,转载请注明出处,谢谢合作。