iOS開發(fā)中我們有時需要代碼預(yù)先計算出字符串的寬高來進行特殊布局凳枝,在iOS7以后,計算字符串高度使用boundingRectWithSize
方法,
- 創(chuàng)建并設(shè)置label控件
UILabel *label = [UILabel new];
label.userInteractionEnabled = NO;
label.textAlignment = NSTextAlignmentCenter;
label.lineBreakMode = NSLineBreakByCharWrapping;
label.numberOfLines = 0;
- 計算字符長度 (一個很長的字符串)
str = @"您邀請\"123\"串稀、\"123\"、...... \"123\"狮杨、\"123\"母截、\"123\"加入了群";
NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:14.0]};
CGSize textRect = CGSizeMake([UIScreen mainScreen].bounds.size.width - 30, MAXFLOAT);
CGFloat textHeight = [str boundingRectWithSize:textRect
options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading
attributes:attributes
context:nil].size.height;
Bug表現(xiàn)
上述的代碼執(zhí)行后就會出現(xiàn)高度計算的問題,實際的效果是顯示的文本高度比計算出來的高度少很多橄教,導(dǎo)致出現(xiàn)空白清寇。
然而當(dāng)我把文本內(nèi)容全都換成中文以后卻變正常了,這讓人摸不著頭腦护蝶。
文本換行樣式
- 以單詞為單位換行
label.lineBreakMode = NSLineBreakByWordWrapping;
這種方式將會包含多種規(guī)則
- 英文單詞會作為一個整體不會出現(xiàn)截斷华烟,比如world
- 數(shù)字,例如12345也會作為一個整體
- 各種符號不會出現(xiàn)在行的第一個位置持灰,會將上一行的最后單詞移動到下一行. 包括標(biāo)點符號和其他符號盔夜。例如 ,堤魁。, - ' "" _ [ 等等喂链;
- 還有很多規(guī)則,這些都是為了閱讀起來方便妥泉;
- 以字符為單位換行
label.lineBreakMode = NSLineBreakByCharWrapping;
這種方式就比較簡單了椭微,以單個字符為單位,如果一行顯示不下則換到下一行盲链,從左到右連續(xù)排版沒有其他規(guī)則赏表;
Bug分析
注意上面代碼part1部分UILabel設(shè)置的是以字符NSLineBreakByCharWrapping
為單位換行检诗,而文本計算的時候沒有指定換行方式,系統(tǒng)默認(rèn)的換行方式是以單詞換行瓢剿,上面代碼中的數(shù)字123
和引號\"
還有頓號、
都會被換行規(guī)則限定悠轩,所以以這種排版計算出來的高度會高很多才導(dǎo)致了這個bug
修正后改后的代碼
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.lineBreakMode = NSLineBreakByCharWrapping;
NSDictionary * attributes = @{
NSFontAttributeName:font,
NSParagraphStyleAttributeName: paragraphStyle
};
CGSize textRect = CGSizeMake([UIScreen mainScreen].bounds.size.width - 30, MAXFLOAT);
CGFloat textHeight = [str boundingRectWithSize:textRect
options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading
attributes:attributes
context:nil].size.height;