在很多情景下都会遇到根据文字的内容来动态计算一个控件的大小。
本文以固定控件宽度,动态计算文字高度为示例,其它情况可以同理。
计算一段文字的高度需要固定控件显示宽度,以及确定文字的字体。
创建一个NSString的分类,方法中需要传入字体以及宽度两个参数。
如果文字段落设置了行间距,那么计算高度的时候也要设置行间距的属性。
下面是一个实现了该功能的NSString分类
@interface NSString (ZCLSize)
- (CGFloat)zcl_heightWithFont:(UIFont *)font constrainedToWidth:(CGFloat)width;
- (CGFloat)zcl_heightWithFont:(UIFont *)font constrainedToWidth:(CGFloat)width lineSpacing:(CGFloat)lineSpacing;
@end
@implementation NSString (ZCLSize)
- (CGFloat)zcl_heightWithFont:(UIFont *)font constrainedToWidth:(CGFloat)width {
UIFont *textFont = font ? font : [UIFont systemFontOfSize:[UIFont systemFontSize]];
CGSize textSize;
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.lineBreakMode = NSLineBreakByWordWrapping;
NSDictionary *attributes = @{NSFontAttributeName: textFont,
NSParagraphStyleAttributeName: paragraph};
textSize = [self boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin |
NSStringDrawingTruncatesLastVisibleLine)
attributes:attributes
context:nil].size;
return ceil(textSize.height);
}
- (CGFloat)zcl_heightWithFont:(UIFont *)font constrainedToWidth:(CGFloat)width lineSpacing:(CGFloat)lineSpacing {
UIFont *textFont = font ? font : [UIFont systemFontOfSize:[UIFont systemFontSize]];
CGSize textSize;
NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
paragraph.lineBreakMode = NSLineBreakByWordWrapping;
paragraph.lineSpacing = lineSpacing;
NSDictionary *attributes = @{NSFontAttributeName: textFont,
NSParagraphStyleAttributeName: paragraph};
textSize = [self boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin |
NSStringDrawingTruncatesLastVisibleLine)
attributes:attributes
context:nil].size;
return ceil(textSize.height);
}
@end
使用示例:
文字没有设置行间距。
NSString *showText = @"我不是诗人,所以,只能够把爱你写进程序,\n当作不可解的密码,作为我一个人知道的秘密。\n我以为你是我的唯一,过了很久才发现,你不是我独占的服务器,\n我可以传递,却什么都不能够取回,大师说,此算法不可逆。\n我想析构我自己,却没有多少勇气,只能够注释掉关于你的记忆,\n想寻找你的信息,突然发现,你已经不在我的域。";
UILabel *labelContent = [[UILabel alloc]initWithFrame:CGRectMake(14, 64, CGRectGetWidth(self.view.frame) - 28, CGRectGetHeight(self.view.frame) - 64 - 49)];
[self.view addSubview:labelContent];
labelContent.numberOfLines = 0;
[labelContent setTextColor:[UIColor blackColor]];
[labelContent setFont:[UIFont systemFontOfSize:15]];
[labelContent.layer setBorderWidth:1.0];
[labelContent.layer setBorderColor:[UIColor redColor].CGColor];
[labelContent setText:showText];
CGFloat showTextHeight = [showText zcl_heightWithFont:labelContent.font constrainedToWidth:CGRectGetWidth(self.view.frame) - 28];
labelContent.frame = CGRectMake(14, 64, CGRectGetWidth(self.view.frame) - 28, showTextHeight);
文字设置了行间距
NSString *showText = @"我不是诗人,所以,只能够把爱你写进程序,\n当作不可解的密码,作为我一个人知道的秘密。\n我以为你是我的唯一,过了很久才发现,你不是我独占的服务器,\n我可以传递,却什么都不能够取回,大师说,此算法不可逆。\n我想析构我自己,却没有多少勇气,只能够注释掉关于你的记忆,\n想寻找你的信息,突然发现,你已经不在我的域。";
UILabel *labelContent = [[UILabel alloc]initWithFrame:CGRectMake(14, 64, CGRectGetWidth(self.view.frame) - 28, CGRectGetHeight(self.view.frame) - 64 - 49)];
[self.view addSubview:labelContent];
labelContent.numberOfLines = 0;
[labelContent setTextColor:[UIColor blackColor]];
[labelContent setFont:[UIFont systemFontOfSize:15]];
[labelContent.layer setBorderWidth:1.0];
[labelContent.layer setBorderColor:[UIColor redColor].CGColor];
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:showText];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setLineSpacing:12];
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [showText length])];
labelContent.attributedText = attributedString;
CGFloat showTextHeight = [showText zcl_heightWithFont:labelContent.font constrainedToWidth:CGRectGetWidth(self.view.frame) - 28 lineSpacing:12];
labelContent.frame = CGRectMake(14, 64, CGRectGetWidth(self.view.frame) - 28, showTextHeight);
总结
- 本文给出了固定文字显示宽度以及文字字体,动态计算文字显示高度的方法。
- 同理可以得出固定显示高度,动态计算文字宽度的方法。
- 示例中同时也给出了怎样设置文字的行间距的方法。另一篇博客中也有介绍到。http://www.jianshu.com/p/3bc837edee1b