UITableViewCell 高度自适应
Posted brave-sailor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UITableViewCell 高度自适应相关的知识,希望对你有一定的参考价值。
UITableViewCell 高度自适应一直是我们做动态Cell高度时遇到的最烦躁的问题,Cell动态高度计算可以去看看sunny的这篇文章介绍,今天主要和大家分享下我在使用systemLayoutSizeFittingSize
系统自带方法计算高度的一些心得!
Demo gif
先看原函数注释
/* The size fitting most closely to targetSize in which the receiver‘s subtree can be laid out while optimally satisfying the constraints. If you want the smallest possible size, pass UILayoutFittingCompressedSize; for the largest possible size, pass UILayoutFittingExpandedSize. Also see the comment for UILayoutPriorityFittingSizeLevel. */- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize NS_AVAILABLE_ios(6_0); // Equivalent to sending -systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority: with UILayoutPriorityFittingSizeLevel for both priorities.
从注释中我们可以看出,当你的约束条件配置好后它可以计算出最接近目标的Size,那我们该如何下手呢?
1.首先我们需要建一个UITableViewCell
假如我们Cell的布局如下所示:
Cell所对应的Class我们取名为ZHCalculateTableViewCell
所带属性我们定义为:
@interface ZHCalculateTableViewCell : UITableViewCell @property (weak, nonatomic) IBOutlet UILabel *TitleLabel; @property (weak, nonatomic) IBOutlet UILabel *ContentLabel; @property (weak, nonatomic) IBOutlet UIImageView *showImgView; @property (weak, nonatomic) IBOutlet UILabel *UseNameLabel; @property (weak, nonatomic) IBOutlet UILabel *TimeLabel; @property (strong, nonatomic) ZHCalculateHeightModel *model; @end
看到这里也许你会疑惑ZHCalculateHeightModel
是什么,它是我们Cell所要展示的数据来源!
2.然后我们为我们的Cell建个数据模型
Cell的模型名称我们暂定为:ZHCalculateHeightModel
所带属性:
@interface ZHCalculateHeightModel : NSObject @property (nonatomic, strong) NSString *title; @property (nonatomic, strong) NSString *content; @property (nonatomic, strong) NSString *username; @property (nonatomic, strong) NSString *time; @property (nonatomic, strong) NSString *imageName;
Ok,数据模型建立好了,展示的TableViewCell也有了, Just Show it~
3. 建一个继承于UITableViewController
的ZHCustomLayoutTableViewController
-
建一个在函数
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
中调用的Cell:@property (nonatomic, strong) ZHCalculateTableViewCell *prototypeCell;
-
注册Cell
[self.tableView registerNib:[UINib nibWithNibName:@"ZHCalculateTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:CellIdentifier]; self.tableView.estimatedRowHeight = 100;//很重要保障滑动流畅性 self.prototypeCell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
-
动态计算高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { ZHCalculateTableViewCell *cell = self.prototypeCell; cell.contentView.translatesAutoresizingMaskIntoConstraints = NO; [self configureCell:cell atIndexPath:indexPath];//必须先对Cell中的数据进行配置使动态计算时能够知道根据Cell内容计算出合适的高度 /*------------------------------重点这里必须加上contentView的宽度约束不然计算出来的高度不准确-------------------------------------*/ CGFloat contentViewWidth = CGRectGetWidth(self.tableView.bounds); NSLayoutConstraint *widthFenceConstraint = [NSLayoutConstraint constraintWithItem:cell.contentView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:contentViewWidth]; [cell.contentView addConstraint:widthFenceConstraint]; // Auto layout engine does its math CGFloat fittingHeight = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height; [cell.contentView removeConstraint:widthFenceConstraint]; /*-------------------------------End------------------------------------*/ return fittingHeight+2*1/[UIScreen mainScreen].scale;//必须加上上下分割线的高度 } #pragma mark Configure Cell Data - (void)configureCell:(ZHCalculateTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { cell.model = [dataArray objectAtIndex:indexPath.row];//Cell中对其进行处理 }
ZHCalculateTableViewCell Model的Set函数重写为
#pragma mark - Setters -(void)setModel:(ZHCalculateHeightModel *)model { _model = model; self.TitleLabel.text = model.title; self.ContentLabel.text = model.content; self.showImgView.image = model.imageName.length > 0 ? [UIImage imageNamed:model.imageName] : nil; self.UseNameLabel.text = model.username; self.TimeLabel.text = model.time; }
扩展
我们可以在计算高度后对其进行缓存,下次可以直接返回!
总结
-
在
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
一定不要用ZHCalculateTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
来获取Cell。 -
上述动态计算Cell高度中最最重要的是需要在计算前先初始化Cell中的数据。
-
一定要对ContentView加上宽度约束。
CGFloat contentViewWidth = CGRectGetWidth(self.tableView.bounds); NSLayoutConstraint *widthFenceConstraint = [NSLayoutConstraint constraintWithItem:cell.contentView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:contentViewWidth]; [cell.contentView addConstraint:widthFenceConstraint]; // Auto layout engine does its math CGFloat fittingHeight = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height; [cell.contentView removeConstraint:widthFenceConstraint];
Demo 下载地址
以上是关于UITableViewCell 高度自适应的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewCell嵌套UIWebView并且cell根据webView的内容自适应
UITableViewCell的 Cell 内的图片自适应高度
调整 UILabel 的大小以适应自定义 UITableViewCell 中的文本,无论宽度如何
如何在不滚动 textView 的情况下使 UITableViewCell 的高度扩展以适应 UITextView 的内容并包装文本? (斯威夫特 5)