標籤:
UITableView幾乎是每個app都需要用的控制項,而cell高度自適應也是我們 需要掌握的,當然cell上面的控制項也是有多種表現形式,今天小編講解的是其中一種比較常見的:Auto Layout with UILabel in UITableViewCell。
話不多說,上教程。
首先我們建立一個Sigle View Application的項目,然後拖上一個UITableView到storyboard中,設定好代理並且設定好約束。約束這裡就不做講解了,可以到AutoLayout詳解瞭解一下,接著回到我們項目,我們建立一個繼承UITableViewCell的類,此處我命名為DIYTableViewCell,接著在storyboard中拖一個UITableViewCell到UITableView上,然後把這個cell關聯我們建立的DIYTableViewCell類,什嗎?不會關聯?沒關係,看這裡!
然後給cell一個複用的標識,這裡我命名為cell
接下來我們在cell上面放置一個label和一個UIImageView並且設定好約束,此處注意,應該把UILabel的numberOfLines屬性設定為0.
現在我們應該給ViewController加點料了,回到我們的ViewController,實現UITableView的代理方法,
`#pragma mark - UITableViewDataSource- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.tbData.count;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ DIYTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:iden]; cell.titleLabel.text = [self.tbData objectAtIndex:indexPath.row]; return cell;}`
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
這裡有一個需要特別注意的問題,也是效率問題。UITableView是一次性計算完所有Cell的高度,如果有100個Cell,那麼- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath就會觸發100次,然後才顯示內容。不過在iOS7以後,提供了一個新方法可以避免這100次調用,它就是- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath。 要求返回一個Cell的估計值,實現了這個方法,那隻有顯示的Cell才會觸發計算高度的protocol. 由於systemLayoutSizeFittingSize需要cell的一個執行個體才能計算,所以這兒用一個成員變數存一個Cell的實列,這樣就不需 要每次計算Cell高度的時候去動態產生一個Cell執行個體,這樣即方便也高效也少用記憶體,可謂一舉三得。關於UITableViewCell的最佳化,可以 看這裡最佳化UITableViewCell高度計算
接下來我們聲明一個這樣的執行個體變數:
@property (nonatomic, strong) DIYTableViewCell *cell;
然後執行個體化它:
self.cell = [self.tableView dequeueReusableCellWithIdentifier:iden];
下面是計算cell高度的代碼:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ DIYTableViewCell *cell = (DIYTableViewCell *)self.cell; cell.titleLabel.text = [self.tbData objectAtIndex:indexPath.row]; CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; NSLog(@"調用次數%ld",indexPath.row+1); return MAX(44, 1 + size.height) ;}
可能你會覺得奇怪,為什麼需要加1呢?筆者告訴你,如果不加1,結果就是錯誤的,Cell中UILabel將顯示不正確。原因就是因為這行代碼 CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];由於是在 cell.contentView上調用這個方法,那麼返回的值將是contentView的高度,UITableViewCell的高度要比它的 contentView要高1,也就是它的分隔線的高度。
到這裡我們的cell自適應高度就算完成了,看看我們的運行結果吧:
Domo源碼已經上傳,如有需要可以下載AutoLayoutCell
UITableView使用AutoLayout動態計算cell高度