標籤:
1.iOS8之後利用storyBoard或者xib自訂不等高cell:
對比自訂等高cell,需要幾個額外的步驟(iOS8開始才支援)
- 添加子控制項和contentView(cell的contentView)之間的間距約束(需要代碼控制約束)
- 設定tableViewCell的真實行高和估算行高
// 以下兩行代碼就被蘋果成為self0sizing技術,可惜只能在iOS8及其之後應用// 告訴tableView所有cell的真實高度是自動計算(根據設定的約束來計算)self.tableView.rowHeight = UITableViewAutomaticDimension;// 告訴tableView所有cell的估算高度self.tableView.estimatedRowHeight = 44;
2.iOS8之前利用storyBoard或者xib自訂不等高cell:
- 如果cell內部有自動換行的label,需要設定preferredMaxLayoutWidth屬性
- label之所以知道自己的最大寬度,是因為其要顯示出來的時候,它會根據自己的左右約束或者寬度約束計算出的最大寬度 preferredMaxLayoutWidth。然後根據最大寬度和內容多少計算出來label的實際高度。但這一切的前提是label要顯示出來的時候,如果label不顯示,則不計算preferredMaxLayoutWidth,即preferredMaxLayoutWidth = 0。這時需要手動設定 preferredMaxLayoutWidth
- 因為下面heightForRowAtIndexPath:的cell只是為了計算高度,cell是不會顯示出來的,所以cell上面的label也不會顯示出來,所以需要手動設定label的heightForRowAtIndexPath的值,這裡在cell的awakeFromNib中對 preferredMaxLayoutWidth 進行賦值。
- (void)awakeFromNib{ // 手動設定文字的最大寬度(目的是:讓label知道自己文字的最大寬度,進而能夠計算出自己的frame) self.text_label.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;}
- (void)viewDidLoad { [super viewDidLoad]; // 告訴tableView所有cell的估算高度(設定了估算高度,就可以減少tableView:heightForRowAtIndexPath:方法的調用次數) self.tableView.estimatedRowHeight = 200;}
估算高度的作用:因為tableView繼承自UIScrollView,所以tableView需要根據cell的高度來計算出contentSize。如果不設定估算高度,程式啟動,首先會調用多次heightForRowAtIndexPath:方法(該次數等於資料模型的count)。但如果設定了估算高度,程式會根據給定的估算高度計算出contentSize(計算方法是:估算高度 * 資料模型的count)。只有cell顯示的時候才會調用heightForRowAtIndexPath:方法計算cell的真實高度,這樣一來,heightForRowAtIndexPath:方法的調用次數大大降低,同時也大大提高了效能。
- cell提供一個height的屬性,用於返回cell的高度
- (CGFloat)height{ // 強制布局cell內部的所有子控制項(label根據文字多少計算出自己最真實的尺寸) [self layoutIfNeeded]; // 計算cell的高度 if (self.status.picture) { return CGRectGetMaxY(self.pictureImageView.frame) + 10; } else { return CGRectGetMaxY(self.text_label.frame) + 10; }}
XMGStatusCell *cell;- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ // 建立一個cell(cell的作用:根據模型資料布局所有的子控制項,進而計算出cell的高度,但是因為這個cell不會顯示,所以需要手動設定cell中label的最大寬度) // cell的作用只是為了計算並返回cell的高度,而不是為了返回cell,所以這個cell是打醬油的,這個cell不會被顯示在tableView上,既然也不會被回收到tableView的緩衝池(因為只有曾經顯示到tableView並且已經離開螢幕的cell才會被回收到緩衝池) if (!cell) { cell = [tableView dequeueReusableCellWithIdentifier:ID]; } // 設定模型資料 cell.status = self.statuses[indexPath.row]; return cell.height;}
自訂不等高cell—storyBoard或xib自訂不等高cell