1. 程式人生 > >UILabel換行與多行文字顯示處理

UILabel換行與多行文字顯示處理

最近在專案中頻繁遇到顯示多少行文字的需求,有的需求是在什麼情況下都只顯示1行文字,有的需求是要求顯示多少行文字由伺服器端控制,有的需求是展示全部文字,有的需求是要最多展示5行文字,不過他們有一個共同的特點就是未顯示全的文字用 … 來代替,遇到了這麼多與文字顯示行數有關的需求,因此我把UILabel處理顯示行數的做了一下總結,下面來具體展示一下

需求1 只顯示一行文字

只顯示一行文字其實很好處理,在剛開始學習UILabel的使用時我們已經經常會遇到這種情況,那就是當UILabel的寬度(XXLabel.frame.size.width)不能完全容納所有的文字時,文字就不會全部顯示,在width之外的文字將不會顯示,而用 … 來代替,所以說這是一種很好處理的情況。

你需要做的只是:

  1. 首先設定好UILabel的frame
  2. 把需要顯示的文字賦值給UILabel的text屬性
  3. done

這裡還有一種情況就是,當文字的長度其實是不能充滿你一開始設定的frame的,而你需要使UILabel的長度適應文字的長度,這時你只需要把第三步的改為[XXLbel sizeTofit]即可,我在專案中遇到這種情況是在UILabel之後還需緊跟一個UIImage需要顯示,這樣設定可以使UILabel的長度根據文字來進行自適應,UIImage可以正常進行佈局

需求2 需要顯示全部文字

有時候我們會遇到這樣一種情況,在某個ViewController中一些文字不能完全顯示,我們點選顯示全部,文字則會完全展開,大概就類似於微信朋友圈中點選檢視全部,文字就完全顯示,這樣的情況怎麼處理呢?
其實這種情況也比較好處理,我們只需讓UILabel完全自適應文字即可

你需要做的是:

  1. 首先設定UILabel的frame(其實這裡只需要設定UILabel的寬度即可)
  2. 然後設定UILabel的numberOfLines屬性為0(XXLabel.numberOfLines = 0
  3. 使UILabel自適應文字([XXLabel sizeToFit]

這裡需要解釋一下numberOfLines = 0,在UILabel.h檔案中可以發現蘋果是這樣解釋這個屬性的:

這個屬性是用來決定UILabel中文字有幾行需要繪製,同時決定當UILabel的sizeToFit方法被呼叫時該怎麼做。numberOfLines的預設值是1,即如果你不設定這個屬性的話,UILabel預設只顯示一行文字。接下來的一句話需要注意,當這個值被設定為0時代表沒有限制,可以顯示任意多行,根據你的文字來設定多少行,如果文字的高度超過一行的高度、或者UILabel的高度小於文字的高度,文字就會使用UIlabel的lineBreakMode的屬性值來對文字進行刪節

注意到上面一段文字中的最後一段話,我們發現如果文字的高度超過一行的高度、或者UILabel的高度小於文字的高度,文字就會使用UIlabel的lineBreakMode的屬性值來對文字進行刪節,因此如果你還希望使用…來代表未顯示的字元的話,需要將UILabel的lineBreakMode屬性設定為NSLineBreakByTruncatingTail

lineBreakMode的型別是一個列舉值,型別是NSLineBreakMode,在這裡貼出NSLineBreakMode的定義,可以根據需要使用不同的列舉值

typedef NS_ENUM(NSInteger, NSLineBreakMode) {
NSLineBreakByWordWrapping = 0,  // Wrap at word boundaries, default
NSLineBreakByCharWrapping,     // Wrap at character boundaries
NSLineBreakByClipping,         // Simply clip
NSLineBreakByTruncatingHead,    // Truncate at head of line: "...wxyz"
NSLineBreakByTruncatingTail,    // Truncate at tail of line: "abcd..."
NSLineBreakByTruncatingMiddle   // Truncate middle of line:  "ab...yz"
} NS_ENUM_AVAILABLE(10_0, 6_0);

需求3 伺服器端控制顯示多少行文字

遇到這種需求的時候不要慌,首先需要跟PM詳細詢問,是伺服器控制某個頁面所有的UILabel都使用一個值來控制行數顯示還是針對每一個UILabel都有一個相應的值來進行控制行數顯示。其實這個顯示行數的沒有必要由伺服器來控制,客戶端完全可以做這樣的事,用不到伺服器,伺服器只要把需要的顯示的文字傳回來就行了,這種情況也是因為PM對技術不太屬性導致的,所以一定要與PM說清楚這一點,不然有可能你最終寫出來的程式碼需要重寫。

好了,現在我們假定PM一定要伺服器控制顯示多少行,我們也有相應的做法:

  1. 設定UILabel的frame(不能只設置寬度,高度也要設定,原因在下面會說到)
  2. 從伺服器返回的值中解析出需顯示的行數
  3. 將UILabel的numberOfLines設定為第2步中的行數
  4. 對行數進行判斷,如果行數為1,就不用sizeToFit(因為numberOfLines = 0時,呼叫sizeToFit就不會顯示…),否則,需要呼叫[XXLabel sizeToFit]

搞定

需求4 最多顯示5行,文字不夠5行的有多少行顯示多少行

這種需求比較常見,比如說微信朋友圈中,超過多少行就會顯示收起按鈕,剩下的文字應…來代替,沒超過那個行數就有多少行顯示多少行,有可能在做社群啊、貼吧啊之類的地方會遇到這樣的需求

遇到這樣的需求也不要慌,也有相應的解決辦法

  1. 同樣是設定UILabel的Frame(不用設定高度)
  2. 計算出完全展示文字需要多少高度,這裡需要使用NSString的boundingRectWithSize:options:attributes:context:方法,將size的寬度使用UILabel.frame.size.width,高度可以設定一個很大的值(10000),如果你對計算文字顯示高度的選項有需求可以將指定的NSStringDrawingOptions型別的值傳入option引數(注意這些值可以同時使用),如果你對文字的屬性有要求可以將相應的屬性傳入attribute引數,context引數一般可以傳nil(因為我發現傳nil就能完成任務,對context引數沒有詳細瞭解,挖個坑,以後回來補上)
  3. 使用UIFont的lineHeight屬性得到每一行的高度
  4. 使用第2步中得到的文字高度除以每一行的高度即可得到文字的行數
  5. 對第4步中得到的行數進行判斷,如果 行數 <= 5,UILabel的numberOfLines屬性設定為0,否則UILabel的numberOfLines屬性設定為5
  6. 呼叫[XXUILabel sizeToFit]方法

搞定

我寫了一個小demo來展示這幾種情況,稍後我會把程式碼上傳到GitHub,在寫這篇文章的時候我注意到了自己還有好多東西不太明白,比如說UIView的sizeTofit方法,比如說boundingRectWithSize:options:attributes:context:中context引數,接下來我會多這些東西進行學習,把學習筆記整理出來