内容简介:项目中有一个页面为活动详情页,其中活动的相关内容放置于一个底色为白色的view中,其他的背景色为灰色。效果完成图如下因为内容分为活动时间、金额、规则等且有横线隔开,所以决定用 tableview 来画,创建一个 cell 文件添加内容,再创建一个 controller 在内创建 tableview 承载即可。内容由于分类不同放置于各个 cell 中。然而其中文字内容长度均不同且在后续使用中必定会改变。 cell 的高度根据内容自适应由
项目中有一个页面为活动详情页,其中活动的相关内容放置于一个底色为白色的view中,其他的背景色为灰色。效果完成图如下
因为内容分为活动时间、金额、规则等且有横线隔开,所以决定用 tableview 来画,创建一个 cell 文件添加内容,再创建一个 controller 在内创建 tableview 承载即可。
内容由于分类不同放置于各个 cell 中。然而其中文字内容长度均不同且在后续使用中必定会改变。 cell 的高度根据内容自适应由
//row高自适应 _tableView.rowHeight = UITableViewAutomaticDimension; //给一个预估值,当计算不出时会默认使用此高度 _tableView.estimatedRowHeight = 100; 复制代码
即可设置。
而 tableview 的高度要根据各 cell 高度来计算累加该怎么做呢?
先这样想:计算每一个 cell 的高度,再把它们各自高度的值传至 controller 中进行累加。
首先需要传值,选择用 ReactiveObjc(即RAC) 来进行传值:
在 cell.h 中声明 subject :
@property (nonatomic, strong) RACSubject *subject; 复制代码
cell.m 中懒加载创建:
- (RACSubject *)subject{ if (!_subject) { _subject = [RACSubject subject]; } return _subject; } 复制代码
在创建 cell 的代理中的语句
ABLaborActivityDetailViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier]; 复制代码
一开始,在 cell.m 中的 setLayout 布局方法中,是先走一遍布局,创建控件的,在执行至 cell.index = indexPath.row; 时,才会走 setIndex 方法,给控件内容赋值。
所以要确认何时开始传值,我们要声明一个全局变量
BOOL _isLayout;//状态开关 复制代码
并在布局方法 - (void)setLayout 中一开始令初始状态为 NO
_isLayout = NO; 复制代码
在 setIndex 赋值方法中:
- (void)setIndex:(NSInteger)index{ self.titleLabel.text = self.dataArray[index][@"title"]; self.detailLabel.text = self.dataArray[index][@"detail"]; //通过 index 和数组给 cell 内容赋值时,让开关为 YES ,走几次由我们创建的数组决定,每一次都会走 layoutIfNeeded 方法。 _isLayout = YES; //调用 layoutSubviews 方法 [self layoutIfNeeded]; } 复制代码
也就是走完一次 setLayout 创建空控件后,让 _isLayout = YES;
此时才开始传值,此方法添加在 setLayout 方法末尾:
- (void)layoutSubviews{ [super layoutSubviews]; //每次信号为 YES ,都会通过 RAC 传出 cell 的高度 self.size.height 。 if (_isLayout == YES) { [self.subject sendNext:@(self.size.height)]; //打印 cell高检查 NSLog(@"CELL高=%f",self.size.height); } 复制代码
执行结果打印 cell 高如下,前10行,均为计算空控件赋值前的初始高度(44)-> 得到内容后的高度,循环5次(因为有5个 cell ),后5行即各cell最终高度。
function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=44.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=50.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=44.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=50.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=44.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=50.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=44.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=81.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=44.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=96.500000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=50.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=50.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=50.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=81.000000 function:-[ABLaborActivityDetailViewCell layoutSubviews] line:82 content:CELL高=96.500000 复制代码
这样在 cell 内传值结束, cell 内代码也结束啦
到对应的 controller 中:
需要创建全局变量接收传过来的 cell 高:
{ CGFloat _tableViewHeight;//接收cell的高度 BOOL _isEnd;//刷新开关 } 复制代码
这里有个 BOOL 变量,因为在接收值刷新 tableview 的时候,会出现死循环,为了解决死循环,需给一个开关进行判断何时刷新停止。
在 viewDidLoad 中给两个全局变量以初始状态:
_tableViewHeight = 0;//给初始高度 _isEnd = NO;//给初始状态 复制代码
在 cell 内容代理中:
weakifyySelf; [cell.subject subscribeNext:^(NSNumber *x) { stronggSelf; //接收cell值并累加 _tableViewHeight = _tableViewHeight + [x floatValue]; //在进行到第5行时,并且开关处于 NO 状态,则执行开关切换为YES,防止再次刷新;给 tableview 范围, 并刷新数据,令其显示正确范围,高度计算完毕需按实际情况进行调整,这里 +50 使显示完全 if (indexPath.row == 4 && _isEnd == NO) { _isEnd = YES; self.tableView.size = CGSizeMake(SCREEN_WIDTH - 30, _tableViewHeight+50); [self.tableView reloadData]; } }]; 复制代码
这里再贴一遍最终效果:
一些细节:
活动详情内容,需要给一个最大宽度,考虑适配,应该计算,而不是给确定值,这里例子为(左侧例如“挑战时间”这些title我是给了控件宽度的,计算时要减去):
//自动换行 _detailLabel.numberOfLines = 0; //31、33为左右边距,67为左侧title长度 _detailLabel.preferredMaxLayoutWidth = SCREEN_WIDTH - 31-33 - 67; 复制代码
以上所述就是小编给大家介绍的《iOS初级开发学习笔记:一个页面中自动计算cell的高度来自适应tableView的高度》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 父div高度不能自适应子div高度的解决方案
- Android XML灵活布局之 EditText实现自适应高度同时限制最小和最大高度
- iOS-谈一谈自适应Cell的高度缓存
- UITableViewCell含有WebView的自适应高度新解决方案
- 认知的高度 = 人生的高度
- html – 没有固定高度的滚动条/带滚动条的动态高度
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。