iOS 獲取 Label 高度的正確方式

在設(shè)置 UILabelFrame 高度時(shí)倦畅,不能簡單的設(shè)置為字體的 font size油啤。否則會(huì)將字體的一部分裁剪掉。因?yàn)?UILabel 在不同的字體設(shè)置下碰缔,對 Frame 的高度要求也不一樣赋除,大多數(shù)情況下都比Font的高度設(shè)置要高一些阱缓。

sizeThatFits

使用 viewsizeThatFits 方法。

// return 'best' size to fit given size. does not actually resize view. Default is return existing view size
- (CGSize)sizeThatFits:(CGSize)size;     

例子:

UILabel *testLabel = [[UILabel alloc] init];
testLabel.font = [UIFont systemFontOfSize:30];
testLabel.text = @"Today is a fine day";
CGSize size = [testLabel sizeThatFits:CGSizeMake(200, 30)];
NSLog(@"size = %@", NSStringFromCGSize(size));

輸出:size = {246.33333333333334, 36}

sizeToFit

使用 viewsizeToFit 方法举农。注意:sizeToFit 會(huì)改變 view 原來的 bounds荆针,而 sizeThatFits 不會(huì)。

// calls sizeThatFits: with current view bounds and changes bounds size.
- (void)sizeToFit;                       

例子

UILabel *testLabel = [[UILabel alloc] init];
testLabel.font = [UIFont systemFontOfSize:30];
testLabel.text = @"Today is a fine day";
[testLabel sizeToFit];
NSLog(@"size = %@", NSStringFromCGSize(testLabel.frame.size));

輸出:size = {246.33333333333334, 36}

sizeWithAttributes

使用 NSStringsizeWithAttributes 方法颁糟。

- (CGSize)sizeWithAttributes:(nullable NSDictionary<NSString *, id> *)attrs NS_AVAILABLE(10_0, 7_0);

例子

NSString *text = @"Today is a fine day";
UIFont *font = [UIFont systemFontOfSize:30];
CGSize size = [text sizeWithAttributes:@{
                                         NSFontAttributeName : font
                                         }];
NSLog(@"size = %@", NSStringFromCGSize(size));

輸出: size = {246.3134765625, 35.80078125}

boundingRectWithSize

使用 NSStringboundingRectWithSize 方法航背。

// NOTE: All of the following methods will default to drawing on a baseline, limiting drawing to a single line.
// To correctly draw and size multi-line text, pass NSStringDrawingUsesLineFragmentOrigin in the options parameter.
- (CGRect)boundingRectWithSize:(CGSize)size options:(NSStringDrawingOptions)options attributes:(nullable NSDictionary<NSString *, id> *)attributes context:(nullable NSStringDrawingContext *)context NS_AVAILABLE(10_11, 7_0);

參數(shù)的意義:

  1. size
    限制最大寬高, 雖然是自適應(yīng),但是需要限制最大的寬度和高度棱貌。
  • options
    類型為 NSStringDrawingOptions玖媚,用來指明繪制字符串時(shí)的渲染選項(xiàng)。各個(gè)選項(xiàng)如下:

typedef NS_OPTIONS(NSInteger, NSStringDrawingOptions) {
// The specified origin is the line fragment origin, not the base line origin
// 整個(gè)文本將以每行組成的矩形為單位計(jì)算整個(gè)文本的尺寸
NSStringDrawingUsesLineFragmentOrigin = 1 << 0,

// Uses the font leading for calculating line heights
// 使用字體的行間距來計(jì)算文本占用的范圍婚脱,即每一行的底部到下一行的底部的距離計(jì)算
NSStringDrawingUsesFontLeading = 1 << 1, 

// Uses image glyph bounds instead of typographic bounds
// 將文字以圖像符號(hào)計(jì)算文本占用范圍今魔,而不是排版的邊界
NSStringDrawingUsesDeviceMetrics = 1 << 3,

// Truncates and adds the ellipsis character to the last visible line if the text doesn't fit into the bounds specified.
// Ignored if NSStringDrawingUsesLineFragmentOrigin is not also set.
// 如果文本內(nèi)容超出指定的矩形限制,文本將被截去并在最后一個(gè)字符后加上省略號(hào)障贸。
// 如果 NSStringDrawingUsesLineFragmentOrigin 沒有設(shè)置错森,則該選項(xiàng)不生效
NSStringDrawingTruncatesLastVisibleLine NS_ENUM_AVAILABLE(10_5, 6_0) = 1 << 5, 

} NS_ENUM_AVAILABLE(10_0, 6_0);


- attributes
應(yīng)用于字符串的文本屬性。

- context
`NSStringDrawingContext` 類型篮洁,控制調(diào)整字間距和縮放的比例涩维,用于文本繪制時(shí)使用。該參數(shù)傳入 nil 即可袁波。

例子

NSString *text = @"Today is a fine day";
UIFont *font = [UIFont systemFontOfSize:30];
CGRect suggestedRect = [text boundingRectWithSize:CGSizeMake(800, MAXFLOAT)
options:NSStringDrawingUsesFontLeading
attributes:@{ NSFontAttributeName : font }
context:nil];
NSLog(@"size = %@", NSStringFromCGSize(suggestedRect.size));

輸出: size = {200, 35.80078125}

# 四種方式對比
在設(shè)置字體為 30 的情況下瓦阐,前兩種使用 `view` 的方法返回 size = {246.33333333333334, 36},后兩種使用 `NSString` 的方法返回 size = {246.3134765625, 35.80078125}锋叨。使用 `view` 方法比使用  `NSString` 方法的返回的值略大垄分。
> 我猜測其原因都是因?yàn)椋谋句秩疽嬖阡秩疽恍形谋镜臅r(shí)候都需要在label的頂部和底部預(yù)留一小部分空間娃磺,應(yīng)該是出于排版美觀方面的考量薄湿。

在顯示不同的 font size 的字體時(shí),獲得的字符串高度比 font size 大的值是不同的偷卧。
比如 `font size` 為 13 時(shí)豺瘤,算出高度為 16,`font size` 為 20 時(shí)听诸,算出高度為 24坐求。

> 所以平常設(shè)置 UILabel 高度的時(shí)候,也不能簡單的在 font height 基礎(chǔ)之上加隨意值晌梨。

# 參考
[理解NSStringDrawingOptions每個(gè)選項(xiàng)的用法與意義](http://www.itdadao.com/articles/c15a197037p0.html)
[UILabel中一個(gè)很多人都會(huì)踩的坑](http://mp.weixin.qq.com/s?__biz=MzI5MjEzNzA1MA==&mid=2650264215&idx=1&sn=bce53cc5b98eef3f839760a4b9b5002c&chksm=f40683a2c3710ab4af58fa5e39a053c5997c4780da3df0f5acca189b6f8fc15a5c7cc26076f1&scene=0#rd)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末桥嗤,一起剝皮案震驚了整個(gè)濱河市须妻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌泛领,老刑警劉巖荒吏,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異渊鞋,居然都是意外死亡绰更,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門锡宋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來儡湾,“玉大人,你說我怎么就攤上這事执俩⌒炷疲” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵奠滑,是天一觀的道長丹皱。 經(jīng)常有香客問我,道長宋税,這世上最難降的妖魔是什么摊崭? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮杰赛,結(jié)果婚禮上呢簸,老公的妹妹穿的比我還像新娘。我一直安慰自己乏屯,他們只是感情好根时,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著辰晕,像睡著了一般蛤迎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上含友,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天替裆,我揣著相機(jī)與錄音,去河邊找鬼窘问。 笑死辆童,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的惠赫。 我是一名探鬼主播把鉴,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼儿咱!你這毒婦竟也來了庭砍?” 一聲冷哼從身側(cè)響起场晶,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎怠缸,沒想到半個(gè)月后峰搪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凯旭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了使套。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罐呼。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖侦高,靈堂內(nèi)的尸體忽然破棺而出嫉柴,到底是詐尸還是另有隱情,我是刑警寧澤奉呛,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布计螺,位于F島的核電站,受9級(jí)特大地震影響瞧壮,放射性物質(zhì)發(fā)生泄漏登馒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一咆槽、第九天 我趴在偏房一處隱蔽的房頂上張望陈轿。 院中可真熱鬧,春花似錦秦忿、人聲如沸麦射。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽潜秋。三九已至,卻和暖如春胎许,著一層夾襖步出監(jiān)牢的瞬間峻呛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工呐萨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留杀饵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓谬擦,卻偏偏與公主長得像切距,于是被迫代替她去往敵國和親赞季。 傳聞我的和親對象是個(gè)殘疾皇子忘伞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

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