IOS 6.0+ Autolayout — UITableViewCell 高度調整

來源:互聯網
上載者:User

標籤:

  • 要實現的效果
  • 要求:
  • storyboard上的準備工作 
  • 建好cell自訂AutoCell 類,關聯好控制項,事先準備好一些資料來源
  • 實現tableview的委託方法
  • 核心部分,HeightForRow方法實現
  • 具體的計算高度方法是現在自訂cell類中
  • 幾大需要注意的地方
  • 在ios6.0上測試
要實現的效果要求:

一般titleLabel 僅顯示一列名,高度為固定。

imageview 大小也為固定。

detailLabel 寬度固定,但高度根據文本動態調整。 

cell 底部拒imageview 的底部以及detailLabel 底部高度都是大於等於20。

當detailLabel文字很少時,cell底部拒imageview底部維持20,這時detaillabel底部距cell 底部大於20. 

當detailLabel文字很多時,cell底部距imageview底部超過20,與detailLabel底部高度維持20.

 

storyboard上的準備工作 

注意將detailLabel numberOfLines 設為0

建好cell自訂AutoCell 類,關聯好控制項,事先準備好一些資料來源?
123     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];
實現tableview的委託方法?
1234567891011121314151617 //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上都沒有得到想要的效果

IT‘S SO BAD!!!

核心部分,HeightForRow方法實現?
1234567891011121314 -(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;}
具體的計算高度方法是現在自訂cell類中?
1234567891011121314 -(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顯示多少行與它的寬度肯定有關,所有這裡要設定正確的寬度,但這裡有點坑的地方

 

這是storyboard 上detailLabel 的該屬性,預設是沒有勾選的(automatic)表示系統自動計算最大布局寬度,但是查看官方文檔,你會發現自動計算只有在ios8中才會有效果,低於ios8不會自動計算。這時你可能會說:那把它勾上吧!!!

,勾上之後你發現顯示的是492,這是什麼意思?這個數字是當前使用的storyboard 的寬度減去label到兩邊界的絕對距離。xcode6 為大尺寸storyboard 寬度600 ,減去 detailLabel 距左邊界98,減去距右邊界10,剛好492.

但是這樣對嗎?很明顯不對,iphone 螢幕寬度不是已經有3種寬度了嗎?320、375(iphone6)、414(plus)

所以600很明顯不對,應該用當前啟動並執行寬度來減去108,所以這裡勾不勾都是錯,乾脆不勾了直接代碼算吧....

?
1 CGFloat preMaxWaith =[UIScreen mainScreen].bounds.size.width-108;
  • 關於layoutIfNeeded到底是幹嘛的,我也是一知半解,只知道不加效果出不來,打算之後再去查閱...

  • 加1是關鍵 

?
12 [self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];return size.height+1.0f;

這裡size.height 實際上是我們要的contentview 的高度,但是我們如果直接將這個高度返回,就賦給了cell的高度,但是由於cell 分界線的原因,cell的高度比contentview高度多1,所以這裡加1再返回。不要小看1像素,少了它效果還真就出不來!!!!

注意了這些,我們再運行,發現得到了想要的效果,切換模擬器,也沒問題。

 

在ios6.0上測試

沒有6.0的模擬器了,找了台6.0的真機,測試後效果

 

detailLabel的高度始終沒有改變,維持在一行,但是可以發現cell的高度是對的,這似乎說明heightforrow方法沒問題,那detailLabel為何沒有自動展開呢?

再次檢查了代碼,原來問題出在cellforrow方法中,因為每個cell上的detailLabel的高度要展開就應該給每個detailLabel設定最大布局寬度:preferredMaxLayoutWidth。之前做的僅僅只是在heightforrow裡面的得到那個用來計算的cell設定過。所以加了幾句代碼

?
12345678910111213141516 -(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好坑,各種陷阱,好在查閱了中外各種資料,最終還是實現了效果。

項目源碼:https://github.com/zhangxh6931/AutolayoutCell

IOS 6.0+ Autolayout — UITableViewCell 高度調整

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.