iOS 中計算字符串高度 - 換行樣式問題

iOS開發中我們有時需要代碼預先計算出字符串的寬高來進行特殊布局,在iOS7以后,計算字符串高度使用boundingRectWithSize方法,

  • 創建并設置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表現

上述的代碼執行后就會出現高度計算的問題,實際的效果是顯示的文本高度比計算出來的高度少很多,導致出現空白。
然而當我把文本內容全都換成中文以后卻變正常了,這讓人摸不著頭腦。

文本換行樣式

  • 以單詞為單位換行
    label.lineBreakMode = NSLineBreakByWordWrapping;
    這種方式將會包含多種規則
  1. 英文單詞會作為一個整體不會出現截斷,比如world
  2. 數字,例如12345也會作為一個整體
  3. 各種符號不會出現在行的第一個位置,會將上一行的最后單詞移動到下一行. 包括標點符號和其他符號。例如 ,。, - ' "" _ [ 等等;
  4. 還有很多規則,這些都是為了閱讀起來方便;
  • 以字符為單位換行
    label.lineBreakMode = NSLineBreakByCharWrapping;
    這種方式就比較簡單了,以單個字符為單位,如果一行顯示不下則換到下一行,從左到右連續排版沒有其他規則;

Bug分析

注意上面代碼part1部分UILabel設置的是以字符NSLineBreakByCharWrapping為單位換行,而文本計算的時候沒有指定換行方式,系統默認的換行方式是以單詞換行,上面代碼中的數字123和引號\"還有頓號都會被換行規則限定,所以以這種排版計算出來的高度會高很多才導致了這個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;
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容