iOS中怎样计算一段文字的高度

在很多情景下都会遇到根据文字的内容来动态计算一个控件的大小。

本文以固定控件宽度,动态计算文字高度为示例,其它情况可以同理。

计算一段文字的高度需要固定控件显示宽度,以及确定文字的字体。

创建一个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);
Paste_Image.png

文字设置了行间距

    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);
Paste_Image.png

总结

  • 本文给出了固定文字显示宽度以及文字字体,动态计算文字显示高度的方法。
  • 同理可以得出固定显示高度,动态计算文字宽度的方法。
  • 示例中同时也给出了怎样设置文字的行间距的方法。另一篇博客中也有介绍到。http://www.jianshu.com/p/3bc837edee1b
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • “青衣水袖半遮颜,台上风光唱彩词。演尽红尘千万事,却为过客未曾欢。” 戏子怜人,已成为酸楚而悲伤的角色,她们永...
    gloaming_f22e阅读 645评论 0 2
  • 一觉梦醒,恍如隔世 人为何不能留于梦中? 梦中,冷雨连绵,天地将倾 天空昏暗不分日夜 人人面临生死隔绝 可是,你走...
    清珞兮阅读 246评论 0 4
  • 今天又一次的失败我很坦然,我知道了我其实并没有这么厉害,我只是害怕的多了几分,然后想要去努力,便乱了阵脚,...
    鱼鱼芋头阅读 270评论 0 0
  • 之一包菜 为了抵御寒冷,在冰天雪地,将自己紧紧包裹。每一颗包菜,象一个巨大的拳头,砸向高高的天空,落在厚实的大地。...
    闲不语阅读 377评论 0 2