html ios取文本长度,iOS 文本高度的计算

iOS开发的过程中,总是避免不了各种高度的自适应,如:UILabel、UITextView、UITableViewCell的高度自适应...而这些适应大部分都源自文本的适应。

计算文本高度的方法有很多种,而我们平时的使用中,富文本的使用几率要大于普通文本,下面以富文本为例介绍两种获取文本高度的方式:

第一种:通过UILabel获取文本的高度

NSString *str = @"朱雀桥边野草花,乌衣巷口夕阳斜。旧时王谢堂前燕,飞入寻常百姓家。";

NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:str];

NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];

style.lineSpacing = 10;

UIFont *font = [UIFont systemFontOfSize:14];

[attributeString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, str.length)];

[attributeString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, str.length)];

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 1)];

label.font = [UIFont systemFontOfSize:14];

label.numberOfLines = 0;

label.attributedText = attributeString;

CGSize size = [label sizeThatFits:CGSizeMake(label.frame.size.width, CGFLOAT_MAX)];

NSLog(@"size:%@", NSStringFromCGSize(size));

NSLog(@"label.frame.size:%@", NSStringFromCGSize(label.frame.size));

可以看到打印结果为:

size:{196, 70.5}

label.frame.size:{200, 1}

在label调用完sizeThatFits:之后,会返回根据条件适应好的size(本身的size并不发生改变),可以通过size.height拿到文本适应后的高度。

但是这种方法有些时候取到的高度会有问题,比如要显示的文本为:@"朱雀桥边野草花"时,上面的代码打印的结果为:

size:{98, 27} //单行高度包含了行间距

label.frame.size:{200, 1}

由于上面的代码显示的文本是富文本,文本的高度包含文字高度的同时,还包含有行间距,但是当UILabel显示的内容为1行时,label调用完sizeThatFits:之后返回的size高度是包含行间距的。

当UILabel显示的文本行数大于等于2行时,sizeThatFits:后拿到的高度是准确的,当UILabel显示的文本行数是1行时,拿到的高度需要减去行间距后才是正确的适应高度

第二种:调用字符串的boundingRectWithSize获取文本的高度

NSString *str = @"朱雀桥边野草花,乌衣巷口夕阳斜。旧时王谢堂前燕,飞入寻常百姓家。";

NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:str];

NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];

style.lineSpacing = 10;

UIFont *font = [UIFont systemFontOfSize:14];

[attributeString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, str.length)];

[attributeString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, str.length)];

NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;

CGRect rect = [attributeString boundingRectWithSize:CGSizeMake(200, CGFLOAT_MAX) options:options context:nil];

NSLog(@"size:%@", NSStringFromCGSize(rect.size));

可以看到打印结果为:

size:{196, 70.12109375}

要显示的文本为:@"朱雀桥边野草花"时,上面的代码打印的结果为:

size:{98, 26.70703125} //单行文本的行高同样包含行间距

以上两种方式都能获取到文本的高度,同样在显示富文本时,如果文本的行数是1行,获取到的文本高度都有问题,我们期望得到的是文本的高度(不包含行间距),这时候就需要判断了。

//文本的高度减去字体高度小于等于行间距,判断为当前只有1行

if ((rect.size.height - font.lineHeight) <= style.lineSpacing) {

rect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height-style.lineSpacing);

}

到这里当文本只有1行时,获取准确的高度的问题好像得到了解决。当现实的文本是@"朱雀桥边野草花"时,打印的结果为:

size:{98, 26.70703125} //加判断条件之前

size:{98, 16.70703125} //加判断条件之后

获取的高度确实为字体的高度,不包含行间距了,然而在测试的时候悲催的发现,当显示文本是@"sfklsdkfjsdlfjsdjfd"时,纯英文的一段测试数据,上面代码的打印结果为:

size:{113.4013671875, 6.70703125}

唉,我去,高度怎么变成这么点儿了?在反复测试之后发现,只要文本中包含有中文时,计算单行文本高度就包含行间距,在文本是纯英文时,单行文本的高度不包含行间距(注:2行或2行以上的纯英文计算的高度是没问题的),so...判断条件又变成了下边这样:

if ((rect.size.height - _font.lineHeight) <= paragraphStyle.lineSpacing) {

if ([self containChinese:str]) { //如果包含中文

rect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height-paragraphStyle.lineSpacing);

}

}

//判断如果包含中文

- (BOOL)containChinese:(NSString *)str {

for(int i=0; i< [str length];i++){

int a = [str characterAtIndex:i];

if( a > 0x4e00 && a < 0x9fff){

return YES;

}

}

return NO;

}

到这里问题就算是解决了,由于笔者能力有限,只会利用现掌握的知识解决这种问题,如果有大神有好的办法,还望不吝赐教,分享一下!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值