iOS lineSpacing行間距無效

在我們開發(fā)過程中會遇到乞榨,當(dāng)你的文字很大時沮明,會出現(xiàn)下面的現(xiàn)象


image.png

此時的代碼如下:


//行間距減去 12  上14
    NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
    paraStyle.lineBreakMode = NSLineBreakByCharWrapping;
    //paraStyle.lineSpacing = 20;
    //設(shè)置負(fù)數(shù)沒有效果的
    //paraStyle.lineSpacing = 5 + 15;
    paraStyle.lineSpacing = 0;

    paraStyle.alignment = NSTextAlignmentRight;
    NSDictionary *attributes = @{NSParagraphStyleAttributeName : paraStyle};
    NSMutableAttributedString * astr = [[NSMutableAttributedString alloc] initWithString:self.lab.text attributes:attributes];
    NSDictionary *attribute = @{NSForegroundColorAttributeName : [UIColor blackColor], NSFontAttributeName : [UIFont systemFontOfSize:40]};
    [astr addAttributes:attribute range:NSMakeRange(0, self.lab.text.length)];
    self.lab.attributedText = astr;

此時我設(shè)置的lineSpacing是0本今,但是圖片上的文字間距還是很大闻蛀,怎么改lineSpacing宰僧,都沒有效果材彪,那如何解決這個問題呢?

正確的實現(xiàn)行間距

image.png

紅色區(qū)域是默認(rèn)繪制單行文本會占用的區(qū)域琴儿,可以看到文字的上下是有一些留白的(藍(lán)色和紅色重疊的部分)段化。設(shè)計師是想要藍(lán)色區(qū)域高度為 10pt,而我們直接設(shè)置 lineSpacing 會將兩行紅色區(qū)域中間的綠色區(qū)域高度設(shè)置為 10pt造成,這就是問題的根源了显熏。

那么這個紅色的區(qū)域高度是多少呢?答案是 label.font.lineHeight晒屎,它是使用指定字體繪制單行文本的原始行高喘蟆。

知道了原因后問題就好解決了,我們需要在設(shè)置 lineSpacing 時鼓鲁,減去這個系統(tǒng)的自帶邊距:

NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
    /**zhushi
     (lldb) po _moveTipLabel.font.lineHeight
     47.734375
     (lldb) po _moveTipLabel.font.pointSize
     40
     */
    paragraphStyle.lineSpacing = 10 - (_moveTipLabel.font.lineHeight - _moveTipLabel.font.pointSize);
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
    _moveTipLabel.attributedText = [[NSAttributedString alloc] initWithString:_moveTipLabel.text attributes:attributes];
    

觀察一下效果蕴轨,完美契合:


image.png

關(guān)于行高 lineHeight

如果你只關(guān)心 iOS 設(shè)備上的文本展示效果,那么看到這里就已經(jīng)夠了骇吭。但是我需要的是 iOS 和 Android 展現(xiàn)出一模一樣的效果橙弱,所以光有行間距是不能滿足需求的。主要的原因在前言也提到了,Android 設(shè)備上的文字上下默認(rèn)留白(上一節(jié)圖中藍(lán)色和紅色重疊的部分)和 iOS 設(shè)備上的是不一致的:

image.png

左側(cè)是 iOS 設(shè)備棘脐,右側(cè) Android 設(shè)備斜筐,可以看到同樣是顯示 20 號的字體,安卓的行高會偏高一些蛀缝。在不同的 Android 設(shè)備上使用的字體不一樣顷链,可能還會出現(xiàn)更多的差別。如果不想辦法抹平這差別内斯,就不能真正意義上實現(xiàn)雙端一致了蕴潦。

這時候我們可以通過設(shè)置 lineHeight 來使得每一行文本的高度一致,lineHeight 設(shè)置為 30pt 的情況下俘闯,一行文本高度一定是 30pt潭苞,兩行文本高度一定是 60pt。雖然文字的渲染上會有細(xì)微的差別真朗,但是布局上的差別將被完全的抹除此疹。lineHeight 同樣可以借助 NSAttributedString 來實現(xiàn),示意代碼:

CGFloat lineHeight = 20;
    
    NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
    paragraphStyle.maximumLineHeight = lineHeight;
    paragraphStyle.minimumLineHeight = lineHeight;
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
    _lab.attributedText = [[NSAttributedString alloc] initWithString:_lab.text attributes:attributes];

運行一下觀察效果:


image.png

在 debug 模式下確認(rèn)了下文本的高度的確正確的遮婶,但是為什么文字都顯示在了行底呢蝗碎?

修正行高增加后文字的位置

修正文字在行中展示的位置,我們可以用baselineOffset 屬性來搞定旗扑。這個屬性十分有用蹦骑,在實現(xiàn)上標(biāo)下標(biāo)之類的需求時也經(jīng)常用到它。經(jīng)過調(diào)試臀防,發(fā)現(xiàn)最合適的值是 (lineHeight - label.font.lineHeight) / 4(尚未搞清楚為什么是除以 4 而不是除以 2眠菇,希望知道的老司機(jī)指點一二)。最終的代碼示例如下:

 #pragma mark - 333
    CGFloat lineHeight = 20;
    NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
    paragraphStyle.maximumLineHeight = lineHeight;
    paragraphStyle.minimumLineHeight = lineHeight;
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
    CGFloat baselineOffset = (lineHeight - _lab.font.lineHeight) / 4;
    [attributes setObject:@(baselineOffset) forKey:NSBaselineOffsetAttributeName];
    _lab.attributedText = [[NSAttributedString alloc] initWithString:_lab.text attributes:attributes];
    

貼一下在不同字號和行高下的展示效果:


image.png

行高和行間距同時使用時的一個問題

不得不說行高和行間距我們都已經(jīng)可以完美的實現(xiàn)了袱衷,但是我在嘗試同時使用它們時捎废,發(fā)現(xiàn)了 iOS 的一個 bug(當(dāng)然也可能是一個 feature,畢竟不 crash 都不一定是 bug):


image.png

著色的區(qū)域都是文本的繪制區(qū)域致燥,其中看上去是橙色的區(qū)域是 lineSpacing登疗,綠色的區(qū)域是 lineHeight。但是為什么單行的文本系統(tǒng)也要展示一個 lineSpacing 跋釉椤7妗?坑爹呢這是0嵩帷荷腊?

好在我們通常是行高和行間距針對不同的需求分別獨立使用的,它們在分開使用時不會觸發(fā)這個問題急凰。so 暫且將高度計算的邏輯保持和系統(tǒng)一致了。

那么本文開頭我提出問題的解決方式如下,親測有效

 CGFloat lineHeight = 45;
    NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
    paragraphStyle.maximumLineHeight = lineHeight;
    paragraphStyle.minimumLineHeight = lineHeight;
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    [attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
    
    CGFloat baselineOffset = (lineHeight - _lab.font.lineHeight) / 4;
    
    //[attributes setObject:@(baselineOffset) forKey:NSBaselineOffsetAttributeName];
    
    [attributes setObject:@1 forKey:NSBaselineOffsetAttributeName];
    
    _lab.attributedText = [[NSAttributedString alloc] initWithString:_lab.text attributes:attributes];
    

本文摘自蘋果核
講解行間距抡锈,很詳細(xì)疾忍,僅供學(xué)習(xí)!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末床三,一起剝皮案震驚了整個濱河市一罩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌撇簿,老刑警劉巖聂渊,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異四瘫,居然都是意外死亡汉嗽,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門找蜜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來饼暑,“玉大人,你說我怎么就攤上這事洗做」眩” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵诚纸,是天一觀的道長撰筷。 經(jīng)常有香客問我,道長畦徘,這世上最難降的妖魔是什么毕籽? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮旧烧,結(jié)果婚禮上影钉,老公的妹妹穿的比我還像新娘。我一直安慰自己掘剪,他們只是感情好平委,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著夺谁,像睡著了一般廉赔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上匾鸥,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天蜡塌,我揣著相機(jī)與錄音,去河邊找鬼勿负。 笑死馏艾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播琅摩,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼铁孵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了房资?” 一聲冷哼從身側(cè)響起蜕劝,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎轰异,沒想到半個月后岖沛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡搭独,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年婴削,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片戳稽。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡馆蠕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出惊奇,到底是詐尸還是另有隱情互躬,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布颂郎,位于F島的核電站吼渡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏乓序。R本人自食惡果不足惜寺酪,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望替劈。 院中可真熱鬧寄雀,春花似錦、人聲如沸陨献。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽眨业。三九已至急膀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間龄捡,已是汗流浹背卓嫂。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留聘殖,地道東北人晨雳。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓行瑞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親悍募。 傳聞我的和親對象是個殘疾皇子蘑辑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

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