【Objective-c】 TableView 中Cell 的高度自適應(yīng)

在項(xiàng)目開(kāi)發(fā)中哩都,我們難免會(huì)遇到tableView的Cell的高度自適應(yīng)板乙,在這里就介紹一下經(jīng)常出現(xiàn)的三種情況

1谓松、cell根據(jù)Label的高度而改變

有兩種方法:

方法一:可視化添加約束實(shí)現(xiàn)(即定制Cell)在storyboard和xib的原理是一樣的焕妙,這里以storyboard為例

要根據(jù)Label 的內(nèi)容自適應(yīng)Cell的高度,那么就必須固定寬度才能計(jì)算高度沃斤,這里通過(guò)添加Label兩邊的約束圣蝎,根據(jù)屏幕的大小來(lái)固定寬度的。

寬度固定了衡瓶,那么再給Label添加上下約束徘公,如上圖,這樣系統(tǒng)就可以根據(jù)上下約束的值和Label的高度計(jì)算得出Cell的高度了哮针,這里要注意的有兩點(diǎn):1.Label的行數(shù)要設(shè)置為0关面,才能自動(dòng)換行坦袍。2.因?yàn)镃ell的高度是根據(jù)zongse框Label的高度計(jì)算高度,使用只能給Label添加上下約束缭裆,而“內(nèi)容”的label是不能添加約束的,不然就沖突了

當(dāng)然定制好Cell之后寿烟,還需添加一句代碼

_tableView.rowHeight=UITableViewAutomaticDimension;//自動(dòng)換行(iOS8.0之后是默認(rèn)值澈驼,不用再設(shè)置)
_tableView.estimatedRowHeight = 100;//預(yù)設(shè)高度(注意并不是最小高度)只是為了設(shè)置contentsize

方法二:代碼實(shí)現(xiàn) ,實(shí)現(xiàn)如下圖效果

Label顯示內(nèi)容:
_dataString=@"好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)習(xí)好好學(xué)";
在tableView的HeightForRow代理方法中筛武,動(dòng)態(tài)改變高度

- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath{
   //設(shè)定字體格式
  NSDictionary*fontDt = [NSDictionarydictionaryWithObjectsAndKeys:    [UIFontsystemFontOfSize:17],NSFontAttributeName,nil];
  //設(shè)定寬度計(jì)算高度
  CGRect rect = [_dataString   boundingRectWithSize:CGSizeMake(self.view.frame.size.width-101,0)options:NSStringDrawingUsesLineFragmentOrigin attributes:fontDt context:nil];
  return rect.size.height+22+2;
  //22是Label 上下約束之和
  //2是NSStringDrawingUsesLineFragmentOrigin屬性不包括線條的寬度缝其,所以這里需要添加上下兩條線條的寬度
}

2、Cell根據(jù)TextView輸入的內(nèi)容動(dòng)態(tài)改變高度

同樣實(shí)現(xiàn)方法也分兩種

方法一:在storyboard定制Cell中實(shí)現(xiàn)

分兩步:
第一步:設(shè)置textView的delegate的為Cell徘六,并且在定制的Cell類中的.m 文件中實(shí)現(xiàn) textView的代理方法内边,代碼如下

- (void)textViewDidChange:(UITextView*)textView{
  if([self.delegaterespondsToSelector:@selector(textViewCell: didChangeText:)]) {
      [self.delegatetextViewCell:selfdidChangeText:textView.text];
  }
  CGRectbounds = textView.bounds;
  CGSizemaxSize =CGSizeMake(bounds.size.width,CGFLOAT_MAX);
  CGSizenewSize = [textViewsizeThatFits:maxSize];
  bounds.size= newSize;
  textView.bounds= bounds;
  //讓table view重新計(jì)算高度并刷新  
  UITableView*tableView = [selftableView];
  [tableViewbeginUpdates];
  [tableViewendUpdates]; 
}

- (UITableView*)tableView{
  UIView*tableView =self.superview;
  while(![tableViewisKindOfClass:[UITableViewclass]] && tableView) {
      tableView = tableView.superview;
  }
  return(UITableView*)tableView;
}

最后在VC方法中設(shè)置tableView自適應(yīng)高度就可以了,添加以下代碼

  self.tableView.estimatedRowHeight = 100;
  self.tableView.rowHeight = UITableViewAutomaticDimension;

注意:在VC中不能實(shí)現(xiàn)tableView的heightForCell代理方法待锈,因?yàn)榍懊嬉呀?jīng)設(shè)置了是自適應(yīng)高度的漠其,所以系統(tǒng)會(huì)自己計(jì)算


第二種:使用tableView的heightForCell代理方法實(shí)現(xiàn)(這也是會(huì)經(jīng)常用到的,一個(gè)VC中有可能存在多個(gè)tableView或多種Cell)

在cell的定制中竿音,除了要添加textView的上下左右約束外和屎,也是跟第一種方法一樣,在設(shè)置以下事項(xiàng)


然后在新建的Cell類中春瞬,沒(méi)有什么特殊設(shè)置代碼要添加柴信,就跟平時(shí)一樣就可以了,該拉線就拉線
重點(diǎn)在VC中textView的delegate方法中和tableView的heightForCell方法中宽气,廢話不多說(shuō)随常,直接看代碼

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    NSString *heightString = [_heightRecordDt objectForKey:indexPath];
    //設(shè)置最小高度
    if (heightString.floatValue < 44) {
        return 44;
    }else{
        return heightString.floatValue;
    }
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];
    cell.MyTextView.delegate = self;
    cell.MyTextView.text = [_textViewStringDt objectForKey:indexPath];
    cell.MyTextView.tag = indexPath.section*1000 + indexPath.row;
    cell.MyTextView.scrollEnabled = NO;
    return cell;
}

#pragma mark - textView delegate
- (void)textViewDidChange:(UITextView *)textView{
    NSIndexPath *index = [NSIndexPath indexPathForRow:textView.tag%1000 inSection:textView.tag/1000];
    CGRect rect1 = textView.frame;
    CGSize maxSize = CGSizeMake(rect1.size.width, CGFLOAT_MAX);
    CGSize newSize = [textView sizeThatFits:maxSize];
    rect1.size = newSize;
    textView.frame = rect1;
    
    //保存內(nèi)容,便于cell的復(fù)用
    [_textViewStringDt setObject:textView.text forKey:index];
    NSString *heightString = [_heightRecordDt objectForKey:index];
    //判斷:當(dāng)高度發(fā)生改變的時(shí)候才刷新cell
    //單獨(dú)刷新一個(gè)cell
    if (rect1.size.height != heightString.floatValue) {
        //保存最新高度
        [_heightRecordDt setObject:[NSString stringWithFormat:@"%f",rect1.size.height+12] forKey:index];
        [_tableView beginUpdates];
        [_tableView endUpdates];
    }
}

完整的github:demo
https://github.com/ZeroOnetoo/MZTableViewCell
歡迎各位碼民吐槽萄涯,集思廣益绪氛,會(huì)將最新的技術(shù)更新!涝影!
請(qǐng)多多點(diǎn)贊钞楼,謝謝!袄琳!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末询件,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子唆樊,更是在濱河造成了極大的恐慌宛琅,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,294評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逗旁,死亡現(xiàn)場(chǎng)離奇詭異嘿辟,居然都是意外死亡舆瘪,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)红伦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)英古,“玉大人,你說(shuō)我怎么就攤上這事昙读≌俚鳎” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,790評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵蛮浑,是天一觀的道長(zhǎng)唠叛。 經(jīng)常有香客問(wèn)我,道長(zhǎng)沮稚,這世上最難降的妖魔是什么艺沼? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,595評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮蕴掏,結(jié)果婚禮上障般,老公的妹妹穿的比我還像新娘。我一直安慰自己盛杰,他們只是感情好剩拢,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,718評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著饶唤,像睡著了一般徐伐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上募狂,一...
    開(kāi)封第一講書(shū)人閱讀 49,906評(píng)論 1 290
  • 那天办素,我揣著相機(jī)與錄音,去河邊找鬼祸穷。 笑死性穿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雷滚。 我是一名探鬼主播需曾,決...
    沈念sama閱讀 39,053評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼祈远!你這毒婦竟也來(lái)了呆万?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,797評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤车份,失蹤者是張志新(化名)和其女友劉穎谋减,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體扫沼,經(jīng)...
    沈念sama閱讀 44,250評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡出爹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,570評(píng)論 2 327
  • 正文 我和宋清朗相戀三年庄吼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片严就。...
    茶點(diǎn)故事閱讀 38,711評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡总寻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出梢为,到底是詐尸還是另有隱情渐行,我是刑警寧澤,帶...
    沈念sama閱讀 34,388評(píng)論 4 332
  • 正文 年R本政府宣布抖誉,位于F島的核電站殊轴,受9級(jí)特大地震影響衰倦,放射性物質(zhì)發(fā)生泄漏袒炉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,018評(píng)論 3 316
  • 文/蒙蒙 一樊零、第九天 我趴在偏房一處隱蔽的房頂上張望我磁。 院中可真熱鬧,春花似錦驻襟、人聲如沸夺艰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,796評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)郁副。三九已至,卻和暖如春豌习,著一層夾襖步出監(jiān)牢的瞬間存谎,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工肥隆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留既荚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,461評(píng)論 2 360
  • 正文 我出身青樓栋艳,卻偏偏與公主長(zhǎng)得像恰聘,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子吸占,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,595評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容