1. 程式人生 > >cell高度自適應實現的最簡單方式

cell高度自適應實現的最簡單方式

曾經為了實現cell的高度自適應,不知道吃了多少苦。那個時候,是在我的資料模型model中新增一個height屬性,實現它的get方法,在get方法中計算需要多行顯示文字的高度,然後再加上其他亂七八糟的高度並返回,然後在tableview的
- (CGFloat)tableView:(UITableView )tableView heightForRowAtIndexPath:(NSIndexPath )indexPath中獲取到每行對應的model,取出其中的model.height屬性的值返回,還要在cell中確定cell中label的高度。。。總之就是很麻煩,而且還不一定總能算的很正確,甚是受此困擾。

後來有一天,我終於發現了一個不得了的祕密,只要你懂一定的Autolayout知識的話,原來實現這種的cell高度自適應,其實是灰常灰常簡單的:
首先,第一步,現在自定義的cell中將高度隨著內容動態改變的label的佈局使用autolayout佈局完成,這裡有個注意點就是label和cell邊界的距離要確定好,不能固定死label的高度,然後設定label的numberOfLines=0,行數設定為0即意味著label可以有任意行。
其次,實現以下兩個tableview的delegate中的方法:

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath
*)indexPath { return 10; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { return UITableViewAutomaticDimension; }

是的,只要實現這兩個方法,然後執行你的專案,你會驚訝的發現,哇塞,高度完美自適應…
這裡有幾個關鍵點:
關鍵點1:必須重寫estimatedHeightForRowAtIndexPath方法
這個方法是iOS7.0之後才出現的,如果不重寫此方法,僅重寫heightForRowAtIndexPath,那麼大家會發現,cell並不會根據label的內容,自適應高度。因為系統是先獲取cell的高度,再獲取cell的view。也就是先呼叫heightForRowAtIndexPath,再呼叫cellForRowAtIndexPath。在cellForRowAtIndexPath被呼叫之前,你的label是沒有被設定文字內容的,因此它獲取到的高度,並不是你想要的。那麼我們必須想辦法讓系統在獲取了cell之後,再獲取cell的高度。方法就是,重寫estimatedHeightForRowAtIndexPath,顧名思義,它會返回一個估計高度,有了這個方法後,tableview會先呼叫它獲取估計高度,然後獲取cell,最後獲取真實高度。estimatedHeightForRowAtIndexPath的返回值可以隨意,返回多少都可以,只是給tableview一個安慰而已,讓它延遲獲取真實的高度。
關鍵點2

:真實高度返回值為
UITableViewAutomaticDimension
關鍵點3:cell中的元素,必須相對於cell的頂部和底部佈局,這樣在元素中的內容動態變化的時候,才能撐開cell