前言
作為一枚程序媛妹子,在這條擼碼的道路上越走越遠(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)瞅一瞅哈芝雪!
方法
- 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
- 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)