在项目开发中,由于设计的一些需求,经常需要对UILabel展示文本进行一些处理,往往要用到富文本的内容。刚刚开发完的新版本刚好用到了这个实现,写篇文章总结一下。
实现时主要用到的类NSMutableAttributedString和NSMutableParagraphStyle
1.1 文本最多显示三行,超过三行使用“...”方式截断
主要实现代码:
//获取文字内容的高度
CGFloat textHeight = [self boundingRectWithWidth:kSCREEN_WIDTH - kIPhone6Scale(32) withTextFont:font withLineSpacing:lineSpace text:str].height;
//文字高度超过三行,截取三行的高度,否则有多少显示多少
if (textHeight > font.lineHeight*3+2*lineSpace) {
textHeight = font.lineHeight*3+2*lineSpace;
}
//设置label的富文本
_label.attributedText = [self attributedStringFromStingWithFont:font withLineSpacing:lineSpace text:str];
_label.frame = CGRectMake(kIPhone6Scale(16), 100,kSCREEN_WIDTH - kIPhone6Scale(32) ,textHeight);
计算内容高度:
/**
* 根据文字内容动态计算UILabel宽高
* @param maxWidth label宽度
* @param font 字体
* @param lineSpacing 行间距
* @param text 内容
*/
-(CGSize)boundingRectWithWidth:(CGFloat)maxWidth
withTextFont:(UIFont *)font
withLineSpacing:(CGFloat)lineSpacing
text:(NSString *)text{
CGSize maxSize = CGSizeMake(maxWidth, CGFLOAT_MAX);
//段落样式
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
//设置行间距
[paragraphStyle setLineSpacing:lineSpacing];
//#warning 此处设置NSLineBreakByTruncatingTail会导致计算文字高度方法失效
// [paragraphStyle setLineBreakMode:NSLineBreakByTruncatingTail];
//计算文字尺寸
CGSize size = [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font,NSParagraphStyleAttributeName:paragraphStyle} context:nil].size;
return size;
}
NSString转换成NSMutableAttributedString:
/**
* NSString转换成NSMutableAttributedString
* @param font 字体
* @param lineSpacing 行间距
* @param text 内容
*/
-(NSMutableAttributedString *)attributedStringFromStingWithFont:(UIFont *)font
withLineSpacing:(CGFloat)lineSpacing
text:(NSString *)text{
NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName:font}];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setLineSpacing:lineSpacing];
[paragraphStyle setLineBreakMode:NSLineBreakByTruncatingTail]; //截断方式,"abcd..."
[attributedStr addAttribute:NSParagraphStyleAttributeName
value:paragraphStyle
range:NSMakeRange(0, [text length])];
return attributedStr;
}
以上方法就可以实现最多显示三行文本并用省略号截断多余文字的效果。
踩过的坑也在此处说明一下,避免有人继续踩坑(哈哈哈,都是在坑中成长)
在计算文字高度和设置label的NSMutableAttributedString时没有分开封装,计算文字高度时paragraphStyle设置了NSLineBreakByTruncatingTail属性,导致计算文字高度方法失效,不能正确计算出文字高度。
当文字内容是中文且只有一行的时候,底部会多出一个行间距的空白,想要按照设计图正确设置和下一个控件的距离,要相应的在设计标注的距离上减去空白高度
NSInteger rowNum = textHeight/font.lineHeight
if(rowNum==1)
{
//只有一行文字设置标注时减去行高
}else
{
//不减行高
}
1.2 查看/收起全文
实现效果如上图所示,由于代码比较简单,需要的可以下载demo查看。
https://github.com/susie0924/SLLabelDemo.git