IOS學習之UITableViewCell動態計算高度(IOS8)

上一篇介紹了AutoLayout的三個屬性,後來發現其實和UITableViewCell動態高度的學習關係不大。不過還是有用的,因爲AutoLayout涉及到比較複雜的佈局,就肯定會用到那三個屬性。廢話不多說,今天就來學習一下UITableViewCell的動態計算高度問題。這篇的方法僅適用IOS8以上的系統,稍後在寫一篇通用的。

計算Cell高度這個問題,蘋果終於在IOS8時幫我們做了,也就是self-sizing-cells這個概念。用起來也是很簡單的。

1.你的Cell要使用AutoLayout來佈局約束這是必須的;

2.設置tableview的estimatedRowHeight爲一個非零值,這個屬性是設置一個預估的高度值,不用太精確。

3.設置tableview的rowHeight屬性爲UITableViewAutomaticDimension

就是下面這兩行代碼

tableView.estimatedRowHeight = 37.0;

tableView.rowHeight = UITableViewAutomaticDimension;


接下來你只需要用AutoLayout佈局好Cell,一切就都交給蘋果吧。下面看一下例子:

新建一個Master-detail的項目,模版是包括增刪當前時間的,我們不需要,稍微改一下,顯示一些靜態數據就好。記得加上上面的兩行代碼,修改之後viewDidLoad代碼如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.tableView.estimatedRowHeight = 37.0;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
    self.objects = [NSMutableArray arrayWithArray:@[@"In iOS 8, Apple introduces a new feature for UITableView known as Self Sizing Cells. This is seriously one of the most exciting features for the new SDK. Prior to iOS 8, if you displayed dynamic content in table view with varied row, you need to calculate the row height on your own. In summary, here are the steps to implement when using self sizing cells",@"Add auto layout constraints in your prototype cell",@"Specify the estimatedRowHeight of your table view",@"Set the rowHeight of your table view to UITableViewAutomaticDimension",@"tableView.estimatedRowHeight = 36.0;",@"tableView.rowHeight = UITableViewAutomaticDimension;"]];
}

數據準備好了,接下來我們開始自定義Cell,新建UITableViewCell子類爲DemoTableViewCell,然後我們打開stroyboard。選擇Master Scene中TableView的Cell,將Custom Class改成我們新建的DemoTableViewCell。TableViewCell的style改成Custom。把TableView的Row Height改的高一些。我們現在Cell左邊放一個圖片,設置他的約束如圖:


接着右邊放一個Label,設置約束如圖:


然後打開Assistant editor 把Label連到DemoCell中。如圖:


下面修改一下MasterViewController裏面tableView的代理方法。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    DemoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    cell.cellText.text = self.objects[indexPath.row];
    return cell;
}
運行看下效果如圖:



好吧,原諒我,忘記了一個重要的屬性。返回storyboard,將Label的Lines設置成0,代碼多行。如圖:


運行看下效果


搞定了,和自己計算比起來簡直方便太多。

接下來看看如果在原有的Label下面再加一個需要計算高度的Label會是什麼效果(Label1,Label2)。這就會涉及到約束優先級的問題了。此時Label1的下邊距約束對象應該又superview變成Label2,Label2的上邊距約束對象應該是Label1,Label2的下邊距約束對象是superview。看下修改後出現的問題


因爲兩個Label的高度都是不固定的,所以當Cell高度變大時需要設置誰去被拉伸,xcode推薦我們把Label1的抗拉伸優先級調小,我們按照推薦的來。運行一下看效果:


Label1被拉伸了。反過來修改Label1的抗拉伸優先級大於Label2後,Label2會被拉伸。仔細的觀察了一下Cell的高度,發現其實Cell的高度是正確的,是Label高度的兩倍,只是兩個Label的高度出現了問題,我的想法是如果先按正確高度繪製Label1,然後在繪製Label2,就不會出現這個問題了。仔細一想這樣不對,因爲Label1的下邊距和Label2的上邊距是互相依靠的,這相當於兩個Label的優先級應該一樣纔可以,誰高於誰都不能正確。但都一樣的時候蘋果又不是知道要拉伸的時候該拉伸誰。這時候只能把Label1和Label2的之間的關係拆開才行,決定加一個空的View在Cell中間試試,給View加了一個豎直居中的約束,固定高度爲1,然後讓兩個Label都和View去產生約束,運行看下效果。


問題解決了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章