项目中需要这个效果,于是找度娘,问谷歌,按照其中一位作者的思路自己动手封装;
自定义一个继承于UILabel的Label,直接上代码;
想到边距,首先熟悉的一个词就是UIEdgeInsets
@property(nonatomic, assign) UIEdgeInsets edgeInsets;
外界可以通过这个属性来更改我们这个自定义的Label的边距;
最重要的就是在.m文件中我们要重写两个方法
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines;
- (void)drawTextInRect:(CGRect)rect;
cmd点击进去之后,你会看见官方给的两句注释,大概理解下
// override points. can adjust rect before calling super.
// label has default content mode of UIViewContentModeRedraw
阅读iOS官方文档后,其中第一个方法中bounds
这个参数给出解释是
The bounding rectangle of the receiver.
第二个参数numberOfLines
给出的解释是
The maximum number of lines to use for the label.
The value 0 indicates there is no maximum number of lines and that the rectangle should encompass all of the text.
返回值CGRect类型的解释是
The computed drawing rectangle for the label’s text.
怎么用呢?接着看文档
This method should only be overridden by subclasses that
want to change the receiver’s bounding rectangle before performing any other computations.
Use the value in the numberOfLines
parameter to limit the height of the returned rectangle to the specified number of lines of text.
This method may be called by the system if there was a prior call to the sizeToFit
or sizeThatFits: method. Note that labels in UITableViewCell
objects are sized based on the cell dimensions, and not a requested size.
大概意思就是说这是需要在子类中重写的方法,你不能直接去调用这个方法。当你重写了这个方法之后,使用时应该调用sizeToFit
这个方法,不然的话,这个方法不会被调用。英语不好,凑合着看。
第二个方法
- (void)drawTextInRect:(CGRect)rect;
官方文档也说了
The rectangle in which to draw the text.
需要一个可以描绘出label的矩形来作为这个方法的参数;
使用方法也说了
You should not call this method directly.
This method should only be overridden by subclasses that
want to modify the default drawing behavior for the label’s text.
By the time this method is called, the current graphics context is already configured with
the default environment and text color for drawing.
In your overridden method, you can configure the current context further and then invoke super
to do the actual drawing or you can do the drawing yourself.
If you do render the text yourself, you should not invoke super
大概就是说这个也是你不能直接调用的方法,需要在子类中重写。调用此方法的时候,当前图形上下文已经配置了默认的绘图环境和文本颜色。如果不是自己渲染的话,调用[super drawTextInRect:rect];
看了之后我们就重写方法即可
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines {
UIEdgeInsets insets = self.edgeInsets;
CGRect rect = [super textRectForBounds:UIEdgeInsetsInsetRect(bounds, insets)
limitedToNumberOfLines:numberOfLines];
rect.origin.x -= insets.left;
rect.origin.y -= insets.top;
rect.size.width += (insets.left + insets.right);
rect.size.height += (insets.top + insets.bottom);
return rect;
}
- (void)drawTextInRect:(CGRect)rect {
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, self.edgeInsets)];
}
其中UIEdgeInsetsInsetRect
表示在原来的rect基础上根据边缘距离内切一个rect出来;
然后在需要创建内切Label的时候创建,给之前自定义的属性赋值
showLabel.edgeInsets = UIEdgeInsetsMake(8, 8+2, 8, 8+2);//设置内边距
根据官方文档的说法,我们还得调用一下
[showLabel sizeToFit];//重新计算尺寸,会执行Label内重写的方法
其他设置跟普通label一样,到此大功告成!