在iOS8之前我們需要動態(tài)的計算每個cell的高度,但是iOS8之后,我們就可以使用autolayout自動計算cell的高度, 把這個煩人的高度交給autolayout就行了.
原理很簡單.為了更加簡明的實現(xiàn)效果,就隨便寫一個小demo
首先我們看一下最終效果
cell的樣式:
接下來我們來設(shè)置各個控件的約束
1.設(shè)置Image約束:距屏幕上邊和左邊各10個像素,寬高都是45像素
2.設(shè)置titleLabel約束:距屏幕上邊和右邊各10個像素,距image右邊10像素,不要給高度
3.設(shè)置contentLabel約束:距fromLabel底部10像素,距屏幕左邊和右邊各10像素,
注意:因為contentLabel是最下面的控件,所以一定要設(shè)置他距cell底部的距離(只有設(shè)置這個距離之后,contentLabel高度變化時,他才會去擠壓cell,使cell跟隨著變大)
當(dāng)你設(shè)置玩這些,Xcode會給我們報一個錯誤:
我們點擊進(jìn)去按照xcode上給出的默認(rèn)解決辦法就好,我們的約束都沒有問題,為啥會還會出現(xiàn)這個問題呢,這個就跟Content Hugging Priority 和 Content Compression ResIstance Priority有關(guān)了
Content Hugging Priority 其實就是阻止view變大的力量蛉迹,Content Compression ResIstance Priority是阻止view變小的力量册烈。
由于我們把titleLabel和contentLabel都設(shè)置了距離cell右邊固定距離,所以他兩都有可以是自身變大的力量婿禽,且優(yōu)先級是1000赏僧,也就是說一旦文本內(nèi)容比較多,就會向下拉伸扭倾〉砹悖可是titleLabel和contentLabel都具有變大的力量,而且優(yōu)先級是一樣的膛壹,都是251驾中,當(dāng)出現(xiàn)都要變大時,xcode不知道該優(yōu)先拉伸哪一個為好模聋,所以也就拋出了錯誤肩民。我們只要把contentLabel的Vertical的優(yōu)先級調(diào)大一點就可以了(251->252)×捶剑或者把titleLabel的Vertical的優(yōu)先級調(diào)小一點(251->250)
我們可以看一下現(xiàn)在運行的效果
大家有沒有發(fā)現(xiàn)這個問題,如果標(biāo)題行數(shù)為2行或者以上就沒有問題,如果標(biāo)題為一行話,有些內(nèi)容就會把頭像的下面的部分覆蓋了
為什么會出現(xiàn)這個問題呢?這就要從設(shè)置contentLabe約束l開始說起了,我們設(shè)置contentLabel約束時候,只讓它距titleLabel的底部10個像素,沒有考慮到如果標(biāo)題的高度比頭像的高度小的情況,所以當(dāng)標(biāo)題高度比頭像高度小的話,contentLabel會覆蓋Image.
這個時候我們應(yīng)該怎么設(shè)置contentLabel的約束呢?
在contentLabel原來約束的基礎(chǔ)上,增加一個相對于Image的約束,距Image底部大于等于10像素,然后把距離titleLabel底部的距離設(shè)置為大于等于10像素,這樣Image和titleLabel誰的高度更高,contentLabel就距離高度較高的底部10個像素
以上就是在xib里需要做的事情
接下來是代碼里需要實現(xiàn)的東西:
在控制器中的 viewDidLoad的方法里只需要添加兩句代碼即可
- (void)viewDidLoad {
[super viewDidLoad];
// 設(shè)置數(shù)據(jù)源
_dataArray = @[@"設(shè)置的 AutoLayout 約束必須讓 cell 的 contentView 知道如何自動延展持痰。關(guān)鍵點是 contentView 的 4 個邊都要設(shè)置連接到內(nèi)容的約束,并且內(nèi)容是會動態(tài)改變尺寸的并且內(nèi)容是會動態(tài)改變尺寸的并且內(nèi)容是會動態(tài)改變尺寸的祟蚀。",@"設(shè)置連接到內(nèi)容的約",@"fjdsfds",@"要設(shè)置連接到內(nèi)容的約束工窍,并且內(nèi)容是會動態(tài)改變尺寸會動態(tài)改變尺會動態(tài)改變尺",@"sdfjslfff"].mutableCopy;
_titleArray = @[@"瘋狂的拉薩得思考",@"標(biāo)題的長度要長一點標(biāo)題的長度要長一點標(biāo)題的長度要長一點標(biāo)題的長度要長一點標(biāo)題的長度要長一點標(biāo)題的長度要長一點標(biāo)題的長度要長一點標(biāo)題的長度要長一點",@"sla接發(fā)的是",@"反倒是范德薩發(fā)范德薩發(fā)大廈范德薩發(fā)大廈范德薩范德薩發(fā)范德薩發(fā)大廈反倒是",@"粉絲發(fā)的是拉開富家大室"].mutableCopy;
// 告訴tableView的真實高度是自動計算的,根據(jù)你的約束來計算
self.tableView.rowHeight = UITableViewAutomaticDimension;
// 設(shè)置cell的預(yù)估行高 ,作用:在tablView顯示時候,先根據(jù)估算高度得到整個tablView高,而不必知道每個cell的高度,從而達(dá)到高度方法的懶加載調(diào)用
self.tableView.estimatedRowHeight = 200;
}
實現(xiàn)numberOfRowsInSection方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 5;
}
將cellForRowAtIndexPath方法改為如下樣子
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = @"testcell";
TestTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:@"TestTableViewCell" owner:self options:nil] lastObject];
}
[cell setNeedsUpdateConstraints];
[cell updateConstraintsIfNeeded];
cell.title.text = _titleArray[indexPath.row];
cell.content.text = _dataArray[indexPath.row];
return cell;
}
至此我們所有的工作就完成了,大家有沒有發(fā)現(xiàn),我們沒有一句代碼去實現(xiàn) heightForRowAtIndexPath 方法,但是最終的效果卻實現(xiàn)了cell高度的自適應(yīng)
下面就是最終的效果: