
第一步:創(chuàng)建帶xib的單元格,并且在xib中添加約束
<p>
LayoutCell.h
#import <UIKit/UIKit.h>
@interface LayoutCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIView *a;
@property (weak, nonatomic) IBOutlet UIView *b;
@property (weak, nonatomic) IBOutlet UIView *c;
@property (weak, nonatomic) IBOutlet UIView *d;
@property (assign, nonatomic) NSInteger type;
@end
LayoutCell.m
#import "LayoutCell.h"
@interface LayoutCell()
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bH;// 視圖b的高
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *cH;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *dH;
@end
@implementation LayoutCell
- (void)setType:(NSInteger)type {
switch (type) {
case 0:
{
[self updateHeight:20 c:0 d:0];
}
break;
case 1:
{
[self updateHeight:20 c:40 d:0];
}
break;
case 2:
{
[self updateHeight:20 c:40 d:60];
}
break;
default:
break;
}
[UIView animateWithDuration:0.2 animations:^{
[self.contentView layoutIfNeeded];
}];
}
- (void)updateHeight:(CGFloat)b c:(CGFloat)c d:(CGFloat)d {
self.bH.constant = b;
self.cH.constant = c;
self.dH.constant = d;
}
@end
LayoutCell.xib

<p>
b、c的約束就不贅述了,都是兩邊距離邊框0,上下距離上下視圖各為0,最后高度定值。

視圖a的約束
約束Top Space 決定單元格的上邊界

視圖d的約束
約束Bottom Space 決定單元格的下邊界,注意Bottom Space的邊界是虛線的,
那是因為這個約束的優(yōu)先等級為750,默認是1000
之所以降低優(yōu)先級,那是因為內(nèi)容視圖a、b、c、d之間互相有約束,在單元格高度不確定的情況下內(nèi)容視圖高度必須能夠根據(jù)內(nèi)容確定高度,這樣才能去決定單元格的高度,降低Bottom Space的優(yōu)先級就意味著先考慮其他約束,即等內(nèi)容視圖的約束互相影響確定了自身高度之后,之后,之后(三遍?。?,再根據(jù)Bottom Space調(diào)整單元格高度。
如果不降低Bottom Space的優(yōu)先級,xib會報錯,提示沒有指定子視圖的Y或者高度
注:單元格高度自適應(yīng)只要通過子視圖確定單元格的高度就可以了,寬度還是保持由子視圖去適應(yīng)單元格寬度。
注:autoLayout 出來之后,取代了原先的自適應(yīng)機制autoresizingMask,在UIView中有一個屬性translatesAutoresizingMaskIntoConstraints就是用來指定使用autoLayout還是autoresizingMask的,如果用了xib來創(chuàng)建視圖和約束,translatesAutoresizingMaskIntoConstraints會被自動修改為NO,即啟用autoLayout機制,這個時候約束才有用,根據(jù)約束來自適應(yīng)單元格高度才有效。
@property(nonatomic) BOOL translatesAutoresizingMaskIntoConstraints NS_AVAILABLE_IOS(6_0); // Default YES
</br>
完成第一步后,我們有兩種方式可以實現(xiàn)單元格自適應(yīng),區(qū)別在于api的出現(xiàn)時間,一種iOS8之后才可用,一種iOS6就可以用了。
<b>
</br>
從 iOS6 版本開始適配的方法:
<b>
第二步[iOS6]:聲明單元格變量,保持當(dāng)前單元格
@property(nonatomic,strong) UITableViewCell* prototypeCell;
self.prototypeCell = [self.table dequeueReusableCellWithIdentifier:identifier];
<b>
第三步[iOS6]:在table計算高度的方法中實現(xiàn)高度自適應(yīng)
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
LayoutCell *cell = (LayoutCell *)self.prototypeCell;
// 如果是手動添加的約束,必須將單元格中所有子視圖的translatesAutoresizingMaskIntoConstraints設(shè)為NO,即指定使用約束自適應(yīng)
// 例:cell.translatesAutoresizingMaskIntoConstraints = NO;
// cell.a.translatesAutoresizingMaskIntoConstraints = NO;
// cell.b.translatesAutoresizingMaskIntoConstraints = NO;
// cell.c.translatesAutoresizingMaskIntoConstraints = NO;
// 必須為cell賦值,即完成cellForRow中的任務(wù),因為調(diào)用tableView: heightForRowAtIndexPath:方法時 tableView: cellForRowAtIndexPath方法還沒有調(diào)用,這個時候刷新高度獲取的只是賦值之前的高度,不能實現(xiàn)高度自適應(yīng)的效果
cell.type = [self.array[indexPath.row] integerValue];
// 計算高度
CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingExpandedSize];
NSLog(@"h=%f", size.height + 1);
return 1 + size.height;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
LayoutCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
cell.type = [self.array[indexPath.row] integerValue];
return cell;
}
<b>
第四步[iOS6]:使用單元格高度自適應(yīng)功能
<b>
修改單元格的type屬性,單元格內(nèi)的子視圖約束將變更,這時候便能看到單元格高度自適應(yīng)的效果了
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView beginUpdates];
self.array[indexPath.row] = [NSString stringWithFormat:@"%d",arc4random()%3];
[tableView reloadData];
[tableView endUpdates];
}
</br>
</br>
從 iOS8 版本開始適配的方法:
<b>
第二步[iOS8]:配置table,實現(xiàn)單元格自動計算高度功能
// 二者缺一不可,需要注意的是不能再實現(xiàn)tableView: heightForRowAtIndexPath:方法了,該方法的優(yōu)先級更高,會覆蓋掉rowHeight。
self.table.estimatedRowHeight = 60;
self.table.rowHeight = UITableViewAutomaticDimension;
[self.table registerNib:[UINib nibWithNibName:identifier bundle:nil] forCellReuseIdentifier:identifier];
<b>
第三步[iOS8]:使用單元格高度自適應(yīng)功能
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
LayoutCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
cell.type = [self.array[indexPath.row] integerValue];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView beginUpdates];
self.array[indexPath.row] = [NSString stringWithFormat:@"%d",arc4random()%3];
[tableView reloadData];
[tableView endUpdates];
}
<p>
效果圖:

layoutcell.gif