cell的高度自適應無疑是Ios開發中很頭疼的一道關,但這也有很多思路去克服它。比如現在很流行的第三方框架,還有比較麻煩的自己用純代碼去計算,本篇文章主要通過一個例子JSCellHeightToFit來分析怎么用AutoLayout實現。可以通過github下載這個小DEMO -- JSCellHeightTofit
在Demo中,在使用XIB做好約束后,分為AutoToFit 和 CountToFit 兩種。
AutoToFit值的是cell自己去適應高度的變化。
CountToFit值的是在代碼中再次計算和更改約束。
這也是本文中使用autoLayout實現的兩種思路。來看看代碼就很容易理解了。
AutoToFit
也就是cell自己去適應高度的變化,本例子中主要是用了讓開發過程中比較頭疼的Cell中放TextView來講,讓TextView隨著輸入文字的增長,cell的高度也自動增加。其中用XIB來實現Cell
再此我們要注意的是:
cell的默認高度是44 , 你如果用XIB,要做好約束來撐開整個Cell,使得Cell的高度就是XIB中的高度!
DEMO中AutoToFitCell.xib就是該Cell,約束也相當簡單,唯一非常要注意的是:
textView的Scrolling 中的scrolling enabled 的勾要去掉,否則該約束是失敗的。
在代碼中,我們在控制器AutoToFitViewController中核心代碼為
// 給預估高度
self.tableView.estimatedRowHeight = 100;
self.tableView.rowHeight = UITableViewAutomaticDimension; // 默認,可不設置
estimatedRowHeight是給了一個預估高度,就是說一開始Cell會通過預估高度大致的給出Cell的高度,這是一個重要的說明!
在AutoToFitCell中做了一個代理,并在控制器中實現了這個代理
- (void)textViewCell:(AutoToFitCell *)cell didChangeText:(NSString *)text{
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
NSMutableArray *data = [self.datas mutableCopy];
data[indexPath.row] = text;
self.datas = [data copy];
}
主要是為了保存TextView更新后值,防止在數據在cell重新刷新后丟失!
Cell是怎么樣刷新的呢? 當然不能直接調用Reload方法
在AutoToFitCell.中 使用beginUpdates 來更新,代碼為
UITableView *tableView = [self tableView];
[tableView beginUpdates];
[tableView endUpdates];
讓TableView刷新,并重新計算高度。
就這樣就可以實現TextView的高度自適應了。也就是自動計算的過程,我們沒有任何的計算。
CountToFit
CountToFit 主要是通過代碼重新更改約束,本Demo的例子就是Label的文字變化,我們不知道Label要顯示的文字多少,只能剛開始給其設一個固定高度約束,在代碼中算好這個約束后,重新復制并更改這個約束。我們來看看代碼理解:
我們也正常的給XIB中的Label做好約束后,如下圖
我們將圖片中選中的Height約束像拉控件一樣拉到代碼中
接著我們就到了代碼部分
在CountToFitCell中,我們對要顯示的的文字先做計算
CGSize size = [countStr sizeWithFont:_countLabel.font andMaxSize:CGSizeMake(_countLabel.frame.size.width, MAXFLOAT)];
其中countStr 是要展示的文字,sizeWithFont:andMaxSize:是NSString的Catagory方法,用來計算文字的SIze,計算好后使用
// 核心語句
self.layoutHeight.constant = size.height + 0.1; // 0.1是為了彌補計算中Float的轉化問題
這是我們的重新賦值和更改約束的核心語句。 接下來我們
// 重新定義Cell 的frame
self.frame = CGRectMake(0, 0, self.frame.size.width, size.height + 2 * labelY);
最后再CountToFitViewController 中用
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
AcountToFitCell *cell = (AcountToFitCell *)[self tableView:tableView cellForRowAtIndexPath:indexPath];
return cell.frame.size.height;
}
這樣我們就自己計算好了并實現了高度自適應!
還有很多思路,親愛的朋友們歡迎跟我分享你的思路!