iOS中文行間距富文本高度與顯示那些坑

一、前言
前段時(shí)間來了一個(gè)新設(shè)計(jì)蝌焚,將App的風(fēng)格修改了一遍迟螺。在顯示文字時(shí)赶掖,增加了行間距。原本以為只是展示和計(jì)算高度的時(shí)候添加上富文本的lineSpace屬性即可达箍,但是結(jié)果在顯示一行中文的時(shí)候没龙,卻怎么也計(jì)算字體的時(shí)候多了一個(gè)行間距的高度,展示的Label也多了一個(gè)行間距的高度缎玫。經(jīng)過查找資料硬纤,網(wǎng)上也有人遇到同樣的坑。計(jì)算高度時(shí)赃磨,需要將判斷一下是否中文與一行筝家,如果是一行帶中文并且有行間距,此時(shí)總體高度應(yīng)該減去行間距邻辉。展示的Label如果用的是自適應(yīng)高度溪王,也應(yīng)該做一下判斷,一行中文帶行間距時(shí)值骇,不設(shè)置Label的lineSpace屬性莹菱。如果你也遇到這樣坑,可以通過本文章的Demo解決吱瘩,并封裝好一些方法道伟,便于以后的使用。

二搅裙、文本獲取高度的方式:
通常計(jì)算文本的高度使用以下兩種方式皱卓,通過計(jì)算出來的高度計(jì)算父控件的總高度裹芝。

通過UILabel sizeThatFits獲取文本的高度
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 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));
boundingWithRect
NSString *text = @"恰同學(xué)少年部逮,風(fēng)華正茂";
NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:text];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; style.lineSpacing = 10;
[attributeString addAttribute:NSParagraphStyleAttributeName value:style range:NSMakeRange(0, text.length)];
[attributeString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:14] range:NSMakeRange(0, text.length)]; NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
CGRect rect = [attributeString boundingRectWithSize:CGSizeMake(100, MAXFLOAT) options:options context:nil];
三、中文富文本有行間距的坑:
計(jì)算文字高度的坑:
以上兩種計(jì)算方式在計(jì)算帶有中文嫂易,并且有行間距的富文本時(shí)兄朋,會(huì)出現(xiàn)在計(jì)算一行時(shí),文本高度不對(duì)怜械,多了一個(gè)行間距的高度颅和。但在計(jì)算純英文時(shí)卻不會(huì)存在這個(gè)情況。這樣會(huì)導(dǎo)致在存在父控件時(shí)缕允,父控件整體高度計(jì)算不對(duì)峡扩。

Paste_Image.png
給Label設(shè)置文本的坑:
在給Label設(shè)置富文本時(shí),如果是一行并且?guī)е形恼媳荆⑶以O(shè)置了間距l(xiāng)ineSpace教届,結(jié)果多發(fā)現(xiàn)顯示出來多了一個(gè)間距的高度响鹃。

Paste_Image.png
四、解決方案:
計(jì)算文字高度的坑:
判斷行數(shù)與是否存在中文案训,當(dāng)行數(shù)為一行买置,并且存在中文時(shí),需要將計(jì)算結(jié)果的高度減去行間距强霎。此時(shí)才為正確文本正確高度忿项。
給Label設(shè)置文本的坑:
需要判斷是否超過一行,超過一行不設(shè)置富文本的lineSpace城舞。
//文本的高度減去字體高度小于等于行間距轩触,判斷為當(dāng)前只有1行
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;
    }

Paste_Image.png
五、封裝與使用(便于以后的使用)
對(duì)NSString進(jìn)行以下方法的增加家夺。

/**

  • 計(jì)算文字高度怕膛,可以處理計(jì)算帶行間距的
    */
  • (CGSize)boundingRectWithSize:(CGSize)size font:(UIFont*)font lineSpacing:(CGFloat)lineSpacing
    {
    NSMutableAttributedString *attributeString = [[NSMutableAttributedString alloc] initWithString:self];
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineSpacing = lineSpacing;
    [attributeString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, self.length)];
    [attributeString addAttribute:NSFontAttributeName value:font range:NSMakeRange(0, self.length)];
    NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
    CGRect rect = [attributeString boundingRectWithSize:size options:options context:nil];

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

//文本的高度減去字體高度小于等于行間距,判斷為當(dāng)前只有1行
if ((rect.size.height - font.lineHeight) <= paragraphStyle.lineSpacing) {
    if ([self containChinese:self]) {  //如果包含中文
        rect = CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height-paragraphStyle.lineSpacing);
    }
}


return rect.size;

}

//判斷如果包含中文

  • (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;
    }
    /
    *
  • 計(jì)算最大行數(shù)文字高度,可以處理計(jì)算帶行間距的
    */
  • (CGFloat)boundingRectWithSize:(CGSize)size font:(UIFont*)font lineSpacing:(CGFloat)lineSpacing maxLines:(NSInteger)maxLines{

    if (maxLines <= 0) {
    return 0;
    }

    CGFloat maxHeight = font.lineHeight * maxLines + lineSpacing * (maxLines - 1);

    CGSize orginalSize = [self boundingRectWithSize:size font:font lineSpacing:lineSpacing];

    if ( orginalSize.height >= maxHeight ) {
    return maxHeight;
    }else{
    return orginalSize.height;
    }
    }
    /**

  • 計(jì)算是否超過一行 用于給Label 賦值attribute text的時(shí)候 超過一行設(shè)置lineSpace
    */
  • (BOOL)isMoreThanOneLineWithSize:(CGSize)size font:(UIFont *)font lineSpaceing:(CGFloat)lineSpacing{

    if ( [self boundingRectWithSize:size font:font lineSpacing:lineSpacing].height > font.lineHeight ) {
    return YES;
    }else{
    return NO;
    }
    }

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秦踪,一起剝皮案震驚了整個(gè)濱河市褐捻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌椅邓,老刑警劉巖柠逞,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異景馁,居然都是意外死亡板壮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門合住,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绰精,“玉大人,你說我怎么就攤上這事透葛”渴梗” “怎么了?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵僚害,是天一觀的道長(zhǎng)硫椰。 經(jīng)常有香客問我,道長(zhǎng)萨蚕,這世上最難降的妖魔是什么靶草? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮岳遥,結(jié)果婚禮上奕翔,老公的妹妹穿的比我還像新娘。我一直安慰自己浩蓉,他們只是感情好派继,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布帮坚。 她就那樣靜靜地躺著,像睡著了一般互艾。 火紅的嫁衣襯著肌膚如雪试和。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天纫普,我揣著相機(jī)與錄音阅悍,去河邊找鬼。 笑死昨稼,一個(gè)胖子當(dāng)著我的面吹牛节视,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播假栓,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼寻行,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了匾荆?” 一聲冷哼從身側(cè)響起拌蜘,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎牙丽,沒想到半個(gè)月后简卧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烤芦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年举娩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片构罗。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡铜涉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出遂唧,到底是詐尸還是另有隱情芙代,我是刑警寧澤,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布蠢箩,位于F島的核電站链蕊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏谬泌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一逻谦、第九天 我趴在偏房一處隱蔽的房頂上張望掌实。 院中可真熱鬧,春花似錦邦马、人聲如沸贱鼻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)邻悬。三九已至症昏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間父丰,已是汗流浹背肝谭。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛾扇,地道東北人攘烛。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像镀首,于是被迫代替她去往敵國(guó)和親坟漱。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容