(iOS)使用auto layout進行複雜布局時,UILabel的相關trick

來源:互聯網
上載者:User

(iOS)使用auto layout進行複雜布局時,UILabel的相關trick

 

給心急的同學先說說結論:(因為我也是一個心急的同學)

1. 對於UILabel,設定number of lines相當於設定了一個縱向的constraint;也即意味著,UILabel設定三個constraint就夠了

2. 對於UILabel,橫向設定一個<=的constraint,可以讓UILabel自行適配寬度

3. 文章結尾有測試題哦,喜歡挑戰的同學請往後看

 

一。本文:

先來一段情懷。

第一個項目是純手碼的,MRC,且幾乎沒有使用第三方庫。整天樂呵呵的在紙上計算布局的座標,各種大小都是根據比例Realtime Compute的。缺點顯而易見,布局的代碼太多,把邏輯部分的代碼都擠沒了;好處是,我感覺超可控,幾乎沒有意料外的bug,也不會怕蘋果更新版本影響到app的使用。(註:最新的版本使用storyboard進行介面切換,大多數布局還是手碼的)

第二個項目過於龐大,我使用了Storyboard+auto layout,ARC,數個4位元Star且維護活躍的第三方庫。設計師對UI的控制超精細,auto layout真正讓我從介面布局中解放出來了。不過從最開始機械的使用“橫向兩個constraint+縱向兩個constraint”,到現在主要使用“UITableView-FDTemplateLayoutCell”(https://github.com/forkingdog/UITableView-FDTemplateLayoutCell)進行tableviewcell的布局,還是有些值得討論和學習的地方。

 

 

二。討論對象:

以下均假設情境為使用UITableViewCell進行布局,UITableViewCell內有數個Label/Image/Button等複雜排版。一般而言,Image和Button的大小不變或者和Cell保持比例關係,比較容易處理;而Label則可能由於文字的長短,字型大小的變化,導致寬度和高度上的變化,帶來計算上的麻煩。

 

 

三。設定方法(以下兩個方法各有運用情境)
1:基本款

採用“橫向兩個constraint+縱向兩個constraint”的方法,精確到point的控制每個介面元素的位置和大小。如:

為Label設定了Top, Left, Righ和Height4個屬性,即可完全控制Label的大小。

 

但,若Label中需要顯示的內容可能佔用多行,則可以將number of lines設定為0(有時標題最多顯示兩排時,則可設定為2),然後將Height這個constraint牽出來作為IB Outlet,則可以在程式中隨時修改,如:

 

由於文字長短和cell的寬度均會影響Label的布局,從而決定cell的高度,因此heightForCellAtIndexPath:的傳回值需要通過計算得到。因此此cell會實現兩個函數:

 

+ (CGFloat)cellHeightWithData:(MDDataType*)data withCellWidth:(CGFloat)cellWidth;- (void)updateWithData:(MDDataType*)data;

 

前者class method由heightForCellAtIndexPath:調用,避免執行個體化cell。其中調用

 

[label.text boundingRectWithSize:CGSizeMake(cellWidth, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:label.font} context:nil].size.height

 

 

來計算label的高度,然後合成整個cell的高度

 

後者instance method由cellForRowAtIndexPath:調用,執行個體化cell中的各個控制項參數,然後將上面代碼的計算結果賦值給constraint的IB Outlet.

 

優點:計算快捷效率高,控制精準。

缺點:IB中設定的gap,margin等數值需要和cellHeightWithData此函數中使用的hardcode數值保持一致,一個資料兩方維護,簡直不能忍。另:若Label的字型大小變化,則可能需要重新設定,不方便。

 

 

2. 自適應款

利用constraint中的ratio,multiply,>=,<=等設定,完成auto layout的自動布局。

這個設定是在前面的設定中,刪掉了Height這個constraint,這個時候,可以理解為number of lines充當了第四個constraint,從而可以讓auto layout進行布局。果不其然,auto layout提示說該布局和運行後不符(運行後被auto layout到正確的位置了)。這個warning一方面告訴我們說auto layout可以正確handle這個label,另一方面告訴我們應該用Update Frame這個方法將Label擺放正確。

 

另一種情況,某些label可能無法佔滿整個橫向地區,其後可能會有別的控制項,可以設定<=constraint,使其進行自動布局,

調適型配置,加上前面提到的“UITableView-FDTemplateLayoutCell”(https://github.com/forkingdog/UITableView-FDTemplateLayoutCell),所有關於布局之類的margin,gap等等,就只用在IB中搞定了。幾乎沒必要牽出constraint作為outlet來手動設定了。並且cell所需要實現的函數僅為:

 

- (void)updateWithData:(MDDataType*)data;

在heightForRowAtIndexPath:和 cellForRowAtIndexPath:中均調用此函數即可。【具體請參考UITableView-FDTemplateLayoutCell的文檔和原始碼】

 

優點:布局全部在IB中,代碼中幾乎可以不用管

缺點:由於heightForRowAtIndexPath中需要執行個體化cell,且進行布局計算,因此效率會稍低(當然,會有些最佳化方法)

 

四。使用情境(以下標題均描述uitableview中各個cell的布局難度)
A. 均一高度

hardcode吧,多好啊

(缺圖)

 

B. 易算高度

比如高度和寬度比例為16:9,使用class method進行計算吧,多好啊。

 

+ (CGFloat)cellHeightWithData:(MDDataType*)data withCellWidth:(CGFloat)cellWidth;

(缺圖)

 

 

C. 複雜布局+不需要考慮效率

使用UITableView-FDTemplateLayoutCell吧

(缺圖)

 

D. 複雜布局+效率優先

需要特殊情況特殊對待

(不缺圖)

 

 

五。習題

i) 某個列表由tableview實現,每個cell都有很多資訊,其中Title可長可短,短的顯示一行,長的最多顯示兩行。標題旁顯示Date,有如下四種情況:

情況1:標題佔一行,且可以在右側放置日期,則標題和日期放置在同一行

|------------------------------------------------------|

| Title Short Date |

| (Others) |

 

情況2:標題佔一行,但第一行容納不下日期,日期放在第二行

 

 

|------------------------------------------------------|

| Title Ratherrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr Long |

 

| Date |

| (Others) |

情況3:標題佔兩行,第二行可以在右側防止日期,則日期放置在第二行

 

|------------------------------------------------------|

| Title Verrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr |

 

| rrrrrrrrrrrrrrrry Long Date |

| (Others) |

 


情況4:標題佔兩行,但第二行容納不下日期,則日期放在第二行,標題Trunk Tail,顯示...

 

|------------------------------------------------------|

| Title Terrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr |

 

| rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrriblely ... Date |

| (Others) |

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.