iOS 行距全攻略

設(shè)置行距

UILabel+Utils.m

- (void)setText:(NSString*)text lineSpacing:(CGFloat)lineSpacing {

if (lineSpacing < 0.01 || !text) {

self.text = text;

return;

}

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];

[attributedString addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, [text length])];

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

[paragraphStyle setLineSpacing:lineSpacing];

[paragraphStyle setLineBreakMode:self.lineBreakMode];

[paragraphStyle setAlignment:self.textAlignment];

[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [text length])];

self.attributedText = attributedString;

}

使用

[label setText:text lineSpacing:2.0f];

作為一個四處使用的工具方法,前面的nil檢查很有必要加。因為[[NSMutableAttributedString alloc] initWithString:text]不接受 nil 參數(shù),會直接 crash。

生成的 paragraphStyle 除了配行距之外,還帶上了 label 原有的一些常用屬性。如果有其他需要,也可以加在這里。

UITextView+Utils.m

- (void)setText:(NSString*)text lineSpacing:(CGFloat)lineSpacing {

if (lineSpacing < 0.01 || !text) {

self.text = text;

return;

}

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:text];

[attributedString addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, [text length])];

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

[paragraphStyle setLineSpacing:lineSpacing];

[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [attributedText length])];

self.attributedText = attributedString;

}

UITextView 的方法跟 UILabel 基本一樣。

使用

[textView setText:text lineSpacing:2.0f];

計算行高

自定義行距之后,計算文本高度的方法也得相應(yīng)改。很簡單,只要利用 sizeToFit、sizeThatFits 之類的方法就可以了。

UILabel+Utils.m

+ (CGFloat)text:(NSString*)text heightWithFontSize:(CGFloat)fontSize width:(CGFloat)width lineSpacing:(CGFloat)lineSpacing {

UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, width, MAXFLOAT)];

label.font = [UIFont systemFontOfSize:fontSize];

label.numberOfLines = 0;

[label setText:text lineSpacing:lineSpacing];

[label sizeToFit];

return label.height;

}

UITextView+Utils.m

+ (CGFloat)text:(NSString*)text heightWithFontSize:(CGFloat)fontSize width:(CGFloat)width lineSpacing:(CGFloat)lineSpacing {

UITextView* textView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, width, MAXFLOAT)];

textView.font = [UIFont systemFontOfSize:fontSize];

[textView setText:text lineSpacing:lineSpacing];

[textView sizeToFit];

return textView.height;

}

因為默認(rèn)的 UITextView 有一點 inset,所以計算文本高度的方法要跟 UILabel 分開。

這幾個方法就能應(yīng)付大多數(shù)需求了。根據(jù)自己需要,我還寫了一些參數(shù)帶有 numberOfLines、文本的參數(shù)為 attributedString 的變體。

代碼上的行距 vs 設(shè)計圖上的行距

如果只為貼上面幾個方法,我可能也就懶得寫這篇文章了。這篇文章的重點其實是分享下面這一點:代碼傳參數(shù)進(jìn)去的行距與設(shè)計圖上量出來的行距是有區(qū)別的,代碼上要少幾個像素,而減少的量跟字體大小有關(guān)。

我感覺這一點有時容易被人忽視。例如一個 UILabel 字號為14,有些程序員可能就會把這個 Label 高度定為 14 像素了。而經(jīng)驗豐富的人就會知道不能這樣,否則『h』『g』之類的字母都可能會被切掉一些。在 xib 里,選中 label 之后按『Command + =』會發(fā)現(xiàn)字號為 14 的 label 合適的高度應(yīng)該是 17。

為了給像『g』、『y』英文字母的尾巴留出空間,系統(tǒng)會給 UILabel 上的文字上下加一點默認(rèn)的空白,這就是 font size 與 line height 的區(qū)別。而用代碼設(shè)定paragraphStyle的lineSpacing,是疊加在原有空白之上的。

別小看這點空白。如果設(shè)計師沒有喪心病狂,設(shè)計出的行距往往也就是 4、5 個像素,而對 14 號字來說上下兩行的空白就能占到 3 像素。如果不假思索地直接把設(shè)計圖的標(biāo)注傳進(jìn)去,結(jié)果就是行距放大到150%。視覺上出了偏差,我們也要負(fù)責(zé)任的。

image

行距組成示意圖

由圖所示,視覺上的行距其實由那 3 部分組成:上面一行的默認(rèn)空白 + 行距 + 下面一行的默認(rèn)空白。藍(lán)色高度是我們寫的 lineSpacing,而黃色和綠色加起來正好是一倍font.lineHeight - font.pointSize的值(黃色高度是上面一行的一半,為(font.lineHeight - font.pointSize) / 2,綠色是下面一行的一半)。

簡單打下 log 就可以看到這個差值大概是多少。下面列出常見的字號:

font sizefont.lineHeight(近似)差值

image

為了計算效率高,我們就不在運行時現(xiàn)算這個差值了;直接把設(shè)計圖上量出的行距減去上面這個表里幾個像素的差值,作為參數(shù)傳進(jìn)去即可。例如:14 號字的 label,設(shè)計圖上量出的行距是 5 個像素,那就減去 3 個像素,寫[label setText:text lineSpacing:2.0f];。不要忘了計算行高的時候也要用同樣的參數(shù)~

鏈接:http://www.itdecent.cn/p/50b3d434cbc0

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 9-12章 低頭看了看表,發(fā)覺她太早來了。 抬起頭時,忽然,她的視線像是被釘住般,停在某個朝自己跑來的人影。 為什...
    廣電1701B夏珊珊閱讀 483評論 0 0
  • 抬頭看看,尋覓一些感受,感受到了大太陽帶來的熱感,還有川流不息的車子來來往往。 早早的就感受到了,大太陽帶來的溫度...
    行百里者半九十閱讀 194評論 0 0
  • 今天早上正常上班,下午參加周俊婚禮,看到217的家人,又有一個找到歸屬了,由衷地祝福,祝福白頭偕老,同時也期待,還...
    卓彤的美好時光閱讀 277評論 0 0
  • 二年級陳雨潯 小鴨子和小猴是一對要好的朋友。小鴨子和小猴子一起在一片綠油油的大草原上散步。走著走著,小鴨子一不留神...
    綠沁2閱讀 655評論 0 0

友情鏈接更多精彩內(nèi)容