通常titleLabel 僅顯示一行標題,高度爲固定。ios
imageview 大小也爲固定。git
detailLabel 寬度固定,但高度根據文本動態調整。 github
cell 底部拒imageview 的底部以及detailLabel 底部高度都是大於等於20。xcode
當detailLabel文字不多時,cell底部拒imageview底部維持20,這時detaillabel底部距cell 底部大於20. iphone
當detailLabel文字不少時,cell底部距imageview底部超過20,與detailLabel底部高度維持20.佈局
注意將detailLabel numberOfLines 設爲0測試
nameArray = [NSMutableArray arrayWithObjects:@"蝸殼",@"AI",@"大詹皇",nil]; imageArray = [NSMutableArray arrayWithObjects:@"u=4040080498,3072784853&fm=90&gp=0.jpg",@"u=2384677404,2895132414&fm=21&gp=0.jpg",@"u=262781505,2408318453&fm=21&gp=0.jpg", nil]; descriptionArray = [NSMutableArray arrayWithObjects:@"蝸殼打球好瀟灑,好飄逸,鐵王之王",@"AI,史上最矮狀元,無冕之王,crossover簡直厲害,觀賞性強,永遠的MVP!!!!",@"最年輕的一萬分先生,MVP,奧布萊恩杯,效率之王,天之驕子,全宇宙最強的球員沒有之一,強突暴扣身體棒,髮際線又高了,關鍵時刻又聳了,帶領騎士奪冠吧,雖然看起來還沒戲!!!!!!", nil];
//numberOfRows -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 3; } //cellForRow -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { AutoTableViewCell *cell = (AutoTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"autoCell"]; [cell.titleLabel setText:nil]; [cell.titleLabel setText:[nameArray objectAtIndex:indexPath.row]]; [cell.descriptionLabel setText:nil]; [cell.logoImageView setImage:[UIImage imageNamed:[imageArray objectAtIndex:indexPath.row]]]; [cell.descriptionLabel setText:[descriptionArray objectAtIndex:indexPath.row]]; return cell; }
先不實現HeightForRow方法,直接運行,發現ios7,ios8上都沒有獲得想要的效果spa
IT'S SO BAD!!!code
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { static AutoTableViewCell *cell = nil; static dispatch_once_t onceToken; //只會走一次 dispatch_once(&onceToken, ^{ cell = (AutoTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"autoCell"]; }); //calculate CGFloat height = [cell calulateHeightWithtTitle:[nameArray objectAtIndex:indexPath.row] desrip:[descriptionArray objectAtIndex:indexPath.row]]; return height; }
-(CGFloat)calulateHeightWithtTitle:(NSString*)title desrip:(NSString*)descrip { //這裏很是重要 CGFloat preMaxWaith =[UIScreen mainScreen].bounds.size.width-108; [self.detailLabel setPreferredMaxLayoutWidth:preMaxWaith]; [self.titleLabel setText:title]; //這也很重要 [self.detailLabel layoutIfNeeded]; [self.detailLabel setText:descrip]; [self.contentView layoutIfNeeded]; CGSize size = [self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; //加1是關鍵 return size.height+1.0f; }
首先說爲何要設置 PreferredMaxLayoutWidth, 表示label的最大的佈局寬度,label顯示多少行與它的寬度確定有關,全部這裏要設置正確的寬度,但這裏有點坑的地方orm
這是storyboard 上detailLabel 的該屬性,默認是沒有勾選的(automatic)表示系統自動計算最大布局寬度,可是查看官方文檔,你會發現自動計算只有在ios8中才會有效果,低於ios8不會自動計算。這時你可能會說:那把它勾上吧!!!
如圖,勾上以後你發現顯示的是492,這是什麼意思?這個數字是當前使用的storyboard 的寬度減去label到兩邊界的絕對距離。xcode6 爲大尺寸storyboard 寬度600 ,減去 detailLabel 距左邊界98,減去距右邊界10,恰好492.
可是這樣對嗎?很明顯不對,iphone 屏幕寬度不是已經有3種寬度了麼?320、375(iphone6)、414(plus)
因此600很明顯不對,應該用當前運行的寬度來減去108,因此這裏勾不勾都是錯,乾脆不勾了直接代碼算吧....
CGFloat preMaxWaith =[UIScreen mainScreen].bounds.size.width-108;
關於layoutIfNeeded究竟是幹嗎的,我也是隻知其一;不知其二,只知道不加效果出不來,打算以後再去查閱...
加1是關鍵
[self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; return size.height+1.0f;
這裏size.height 其實是咱們要的contentview 的高度,可是咱們若是直接將這個高度返回,就賦給了cell的高度,可是因爲cell 分界線的緣由,cell的高度比contentview高度多1,因此這裏加1再返回。不要小看1像素,少了它效果還真就出不來!!!!
注意了這些,咱們再運行,發現獲得了想要的效果,切換模擬器,也沒問題。
沒有6.0的模擬器了,找了臺6.0的真機,測試後效果如圖
detailLabel的高度始終沒有改變,維持在一行,可是能夠發現cell的高度是對的,這彷佛說明heightforrow方法沒問題,那detailLabel爲什麼沒有自動拉伸呢?
再次檢查了代碼,原來問題出在cellforrow方法中,由於每一個cell上的detailLabel的高度要拉伸就應該給每一個detailLabel設置最大布局寬度:preferredMaxLayoutWidth。以前作的僅僅只是在heightforrow裏面的獲得那個用來計算的cell設置過。因此加了幾句代碼
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { AutoTableViewCell *cell = (AutoTableViewCell*)[tableView dequeueReusableCellWithIdentifier:@"autoCell"]; [cell.titleLabel setText:nil]; [cell.titleLabel setText:[nameArray objectAtIndex:indexPath.row]]; //補上的幾句,給用來顯示的DetailLabel 設置最大布局寬度 CGFloat preMaxWaith =[UIScreen mainScreen].bounds.size.width-108; [cell.detailLabel setPreferredMaxLayoutWidth:preMaxWaith]; [cell.detailLabel layoutIfNeeded]; [cell.detailLabel setText:nil]; [cell.logoImageView setImage:[UIImage imageNamed:[imageArray objectAtIndex:indexPath.row]]]; [cell.detailLabel setText:[descriptionArray objectAtIndex:indexPath.row]]; return cell; }
再次運行,能夠看到在ios6中也獲得了想要的效果,
IT'S perfect!!!
總之,研究了幾天佈局,發現ios好坑,各類陷阱,好在查閱了中外各類資料,最終仍是實現了效果。