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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容

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