iOS 有關(guān)Cell高度自適應(yīng)的幾種方法(純代碼)

腦容量只能裝這么多.jpeg

前言

作為一枚程序媛妹子,在這條擼碼的道路上越走越遠(yuǎn),表問(wèn):我怎么變這樣~變得這樣瘋狂-_-!(不自覺(jué)哼起了tfboys的歌娜遵,sorry我是狂熱阿姨粉= = )。
開發(fā)這段時(shí)間壤短,一直沒(méi)怎么寫過(guò)博文设拟,沒(méi)好好的去總結(jié)零碎的知識(shí)點(diǎn)(那些零碎的知識(shí)點(diǎn)依舊零碎著= = )so~咳咳,為了強(qiáng)大自我的擼碼水平提高逼格久脯,以此作為開篇文章纳胧,陸續(xù)在空閑時(shí)間整理出常用的實(shí)用的管用的代碼來(lái)鞏固/強(qiáng)化/熟練必要的知識(shí)點(diǎn)。
so~ boys and girls 跟著我左手右手一個(gè)慢動(dòng)作 嘿帘撰!

正題

言歸正傳跑慕,有關(guān)UITableViewCell高度自適應(yīng)的這個(gè)問(wèn)題,我想...對(duì)于絕大多數(shù)的你們?cè)缫巡皇菃?wèn)題摧找,算是給剛?cè)肟拥男“讉冋硪幌聡D核行!純代碼方法,拖拽的別繞道蹬耘,也過(guò)來(lái)瞅一瞅哈芝雪!

請(qǐng)忽略我偷來(lái)的評(píng)論.png

方法

  • 1.普通(或提前)計(jì)算cell的自適應(yīng)高度
  • 2.通過(guò)FrameModel方式獲取cell的自適應(yīng)高度
  • 3.通過(guò)Masonry獲取cell的自適應(yīng)高度

注意:
大前提都是不要忘記在cell.m文件中,給contentLabel添加如下兩行代碼:

contentLabel.numberOfLines = 0;
[contentLabel sizeToFit];

1.普通(或提前)計(jì)算cell的自適應(yīng)高度

我覺(jué)得不必說(shuō)啥吧综苔,算是入門級(jí)的簡(jiǎn)單方法了惩系。
...
...
...
還是說(shuō)一嘴...

普通計(jì)算:
1.在cell.m文件添加:

- (void)layoutSubviews {
    
    [super layoutSubviews];
    
    [self.contentLabel sizeToFit];
}

注意:這里的 [self.contentLabel sizeToFit]要寫在- (void)layoutSubviews方法里。

2.在viewcontroller.m文件中如筛,為方法- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath中添加如下代碼:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    OneModel *model = self.array[indexPath.row];
    NSString *content = model.content;
    
    // 寫法1.
    NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:12.0]};
    
    CGRect contentRect = [content boundingRectWithSize:CGSizeMake([UIScreen mainScreen].bounds.size.width - 20, CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin) attributes:dic context:nil];

    // 寫法2.
    //    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:content];
    //
    //    NSRange allRange = [content rangeOfString:content];
    //
    //    [attrStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:12.0] range:allRange];
    //
    //    [attrStr addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:allRange];
    //
    //    NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
    //    CGRect contentRect = [attrStr boundingRectWithSize:CGSizeMake([UIScreen mainScreen].bounds.size.width - 20, CGFLOAT_MAX) options:options context:nil];
    
    CGFloat contentHeight;
    contentHeight = ceilf(contentRect.size.height);
    
    return  10 + 10 + 10 + contentHeight + 10;// timeHeight + contentHeight
}

搞定~堡牡!就是這么的easy哈哈哈哈哈

提前計(jì)算:
在普通計(jì)算的前提上進(jìn)化的~
1.在cell.h文件中:

/** 
 根據(jù)指定的model數(shù)據(jù)返回當(dāng)前cell的高度
 @param model 數(shù)據(jù)模型
 return cell高度
 */
+ (CGFloat)cellHeightWithModel:(OneModel *)model;

2.在cell.m文件中:

- (void)layoutSubviews {
    
    [super layoutSubviews];
    
    [self.contentLabel sizeToFit];
}
+ (CGFloat)cellHeightWithModel:(OneModel *)model {
    
    NSString *content = model.content;
    
    // 寫法1.
    NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:12.0]};
    CGRect contentRect = [content boundingRectWithSize:CGSizeMake([UIScreen mainScreen].bounds.size.width - 20, CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin) attributes:dic context:nil];
    
    // 寫法2.
//    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:content];
//    NSRange allRange = [content rangeOfString:content];
//    [attrStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:12.0] range:allRange];
//    [attrStr addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:allRange];
//    NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading;
//    CGRect contentRect = [attrStr boundingRectWithSize:CGSizeMake([UIScreen mainScreen].bounds.size.width - 20, CGFLOAT_MAX) options:options context:nil];
    
    CGFloat contentHeight;
    contentHeight = ceilf(contentRect.size.height);
    
    return  10 + 10 + 10 + contentHeight + 10;// timeHeight + contentHeight
}

3.在viewController.m文件中,添加私有方法杨刨,調(diào)用cell創(chuàng)建的+號(hào)方法晤柄,提前計(jì)算出不同的model內(nèi)容對(duì)應(yīng)的cell高度,然后依次添加到一個(gè)數(shù)組中:

#pragma mark - private methods
- (void)loadData {
    
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"DataDemo" ofType:@"plist"];
    NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
    for (NSDictionary *tempDic in data) {
        OneModel *model = [OneModel jxt_initWithDictionary:tempDic];
        [self.array addObject:model];
        
        CGFloat cellHeight = [One2Cell cellHeightWithModel:model];
        [self.heightArray addObject:[NSNumber numberWithFloat:cellHeight]];
    }
    [self.tableView reloadData];
}

在- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath方法中妖胀,直接調(diào)用數(shù)組中對(duì)應(yīng)的高度即可:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    NSNumber *cellHeight = self.heightArray[indexPath.row];
    return cellHeight.floatValue;
}

搞定~可免!

2.通過(guò)FrameModel方式獲取cell的自適應(yīng)高度

此方法需要?jiǎng)?chuàng)建一個(gè)FrameModel,用來(lái)計(jì)算cell的自適應(yīng)高度做粤。

1.創(chuàng)建FrameModel,繼承與NSObject:

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "TwoModel.h"

@interface TwoFrameModel : NSObject

@property (nonatomic, assign) CGFloat cellHeight;

@property (nonatomic, assign) CGRect timeLabelFrame;
@property (nonatomic, assign) CGRect contentLabelFrame;

@property (nonatomic, strong) TwoModel *model;

@end
  1. FrameModel.m中捉撮,計(jì)算每個(gè)frame值怕品,最后計(jì)算cell高度:
- (void)setModel:(TwoModel *)model {
    
    _model = model;
    
    CGFloat timeLabelX = kPadding;
    CGFloat timeLabelY = kPadding;
    CGFloat timeLabelW = kWidth - 20;
    CGFloat timeLabelH = kPadding;
    
    self.timeLabelFrame = CGRectMake(timeLabelX, timeLabelY, timeLabelW, timeLabelH);
    
    
    NSDictionary *dic = @{NSFontAttributeName:[UIFont systemFontOfSize:Kfont]};
    
    CGRect contentLabelRect = [_model.content boundingRectWithSize:CGSizeMake(kWidth - 20, 100000) options:(NSStringDrawingUsesLineFragmentOrigin) attributes:dic context:nil];
    
    CGFloat contentLabelX = kPadding;
    CGFloat contentLabelY = CGRectGetMaxY(self.timeLabelFrame) + kPadding;
    CGFloat contentLabelW = contentLabelRect.size.width;
    CGFloat contentLabelH = contentLabelRect.size.height;
    
    self.contentLabelFrame = CGRectMake(contentLabelX, contentLabelY, contentLabelW, contentLabelH);

    
    // cellHeight
    self.cellHeight = CGRectGetMaxY(self.contentLabelFrame) + kPadding;
}

3.cell.h文件中:

@property (nonatomic, strong) TwoFrameModel *frameModel;

4.cell.m文件中:

- (void)layoutSubviews {
    
    [super layoutSubviews];
    
    self.timeLabel.frame = _frameModel.timeLabelFrame;
    self.contentLabel.frame = _frameModel.contentLabelFrame;
}

- (void)setFrameModel:(TwoFrameModel *)frameModel {
    
    _frameModel = frameModel;
    
    self.timeLabel.text = _frameModel.model.time;
    self.contentLabel.text = _frameModel.model.content;
}

5.在viewcontroller.m文件中

#pragma mark - private methods
- (void)loadData {
    
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"DataDemo" ofType:@"plist"];
    NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:filePath];
    NSLog(@"data:%@", data);
    for (NSDictionary *tempDic in data) {
        TwoFrameModel *frameModel = [[TwoFrameModel alloc] init];
        frameModel.model = [TwoModel jxt_initWithDictionary:tempDic];
        [self.array addObject:frameModel];
    }
    
    [self.tableView reloadData];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    return [self.array[indexPath.row] cellHeight];
}

搞定~!

3.通過(guò)Masonry獲取cell的自適應(yīng)高度

pod Masonry

1.創(chuàng)建tableview時(shí)巾遭,必須給一個(gè)估計(jì)高度:

_tableView.estimatedRowHeight = 175;// 需要給cell高度估計(jì)值肉康,可以隨便給闯估,但不能不給

2.不需要寫- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath方法,寫了的話cell高度以此代理方法為準(zhǔn)了= = 吼和。

3.cell.m文件中涨薪,一定要給最后一個(gè)控件添加bottom距contentview的bottom間距!l排摇刚夺!

#pragma mark - private methods
- (void)setUp {
    
    [self.contentView addSubview:[self timeLabel]];
    [self.contentView addSubview:[self contentLabel]];
    
    [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(kPadding);
        make.left.mas_equalTo(kPadding);
        make.right.mas_equalTo(-kPadding);
    }];
    
    [self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(self.timeLabel.mas_bottom).offset(kPadding);
        make.left.mas_equalTo(kPadding);
        make.right.mas_equalTo(-kPadding);
        make.bottom.mas_equalTo(-kPadding);// 最后一個(gè)控件的bottom是關(guān)鍵點(diǎn)!D┑贰侠姑!
    }];
    
}

OVER~~~~

怎么樣 就是這么的簡(jiǎn)單粗暴!
可能我的方法有問(wèn)題或者不夠巧妙箩做,有更好的方法或是我代碼有不規(guī)范的地方莽红,熱烈歡迎大大們前來(lái)指教!0畎睢安吁!

第一篇正式的博客就寫到這里啦- - (日常追劇去-_-hahaha)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市燃辖,隨后出現(xiàn)的幾起案子鬼店,更是在濱河造成了極大的恐慌,老刑警劉巖郭赐,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件薪韩,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡捌锭,警方通過(guò)查閱死者的電腦和手機(jī)俘陷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)观谦,“玉大人拉盾,你說(shuō)我怎么就攤上這事』碜矗” “怎么了捉偏?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)泻红。 經(jīng)常有香客問(wèn)我夭禽,道長(zhǎng),這世上最難降的妖魔是什么谊路? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任讹躯,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘潮梯。我一直安慰自己骗灶,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布秉馏。 她就那樣靜靜地躺著耙旦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪萝究。 梳的紋絲不亂的頭發(fā)上免都,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音糊肤,去河邊找鬼琴昆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛馆揉,可吹牛的內(nèi)容都是我干的业舍。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼升酣,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼舷暮!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起噩茄,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤下面,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后绩聘,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體沥割,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年凿菩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了机杜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡衅谷,死狀恐怖椒拗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情获黔,我是刑警寧澤蚀苛,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站玷氏,受9級(jí)特大地震影響堵未,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盏触,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一渗蟹、第九天 我趴在偏房一處隱蔽的房頂上張望侦厚。 院中可真熱鬧,春花似錦拙徽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至召庞,卻和暖如春岛心,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背篮灼。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工忘古, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诅诱。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓髓堪,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親娘荡。 傳聞我的和親對(duì)象是個(gè)殘疾皇子干旁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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