UITableViewCell以及其子控件自适应高度

xiaoxiao2021-02-28  10

项目中有一个需求如下图所示:

这是已经的收件箱的cell显示。 另外一种是未读的收件箱的显示,如下图所示:

对于未读的信息的显示,最开始考虑的是将前面的小圆点设置成一个UIImageView,然后后面用UILabel显示正文。但是这样有一个问题就是,第二行的文字和第一行是对齐的,并不是从小圆点的正下方开始显示。而且也不想未读和已读自定义两种cell。 所以最终选择了富文本的方式解决这个问题。

在完成这个功能的时候,遇到的主要问题包括: (1)UITableViewCell的高度自适应 (2)UITableViewCell中的UILabel高度自适应; (3)富文本的高度计算; (4)普通文本的高度计算;

我的思路是:在给UITableViewCell的模型赋值时,在模型的set方法中,根据是否已读,选择文本的计算方式,如果是已读就选择普通的高度计算,如果是未读,就选择富文本计算高度。并设置当前的UIlabel的frame,接着得到UILabel的最大Y值,算出Cell的高度。 在控制器中,在UITableView的代理方法: -(CGFloat)tableView:(UITableView )tableView heightForRowAtIndexPath:(NSIndexPath )indexPath中根据indexPath的到对应的cell,返回这个cell的高度。

具体的代码如下: 自定义的cell中: .h中的代码如下:

#import <UIKit/UIKit.h> #import "GCIWantMessageModel.h" @interface GCIWantRecieveCell : UITableViewCell -(id)initWithReuseIdentifier:(NSString*)reuseIdentifier; @property (nonatomic,strong) GCIWantMessageModel *model; @end

其中GCIWantMessageModel是cell的模型。

.m文件如下:

// // GCIWantRecieveCell.m // GreedyCat // // Created by DH on 2017/6/12. // Copyright © 2017年 GreedyCat. All rights reserved. // #import "GCIWantRecieveCell.h" #define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width) #define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height) @interface GCIWantRecieveCell () @property (nonatomic,strong) UILabel *label; @property (nonatomic,assign) CGFloat cellHeight; @end @implementation GCIWantRecieveCell -(id)initWithReuseIdentifier:(NSString*)reuseIdentifier { self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier]; if (self) { _label = [[UILabel alloc]initWithFrame:CGRectMake(15, 16, SCREEN_WIDTH - 30, 100)]; [self addSubview:_label]; self.selectionStyle = UITableViewCellSelectionStyleNone; } return self; } #pragma mark -给子控件赋值 -(void)setModel:(GCIWantMessageModel *)model { _model = model; self.label.numberOfLines = 0; if(_model.readed == YES){ NSString *tempStr = [[NSString alloc]initWithFormat:@" %@",_model.content]; // 利用富文本进行显示 NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc]initWithString:tempStr]; [attributedStr addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"PingFangSC-Regular" size:16] range:NSMakeRange(0, [tempStr length])]; [attributedStr addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:46/255.0 green:46/255.0 blue:46/255.0 alpha:1.0] range:NSMakeRange(0, [tempStr length])]; // 在最前面添加一个图片 NSTextAttachment *attch = [[NSTextAttachment alloc]init]; attch.image = [UIImage imageNamed:@"check"]; attch.bounds = CGRectMake(0, 1, 8, 8); // 创建带有图片的富文本 NSAttributedString *attributedImageStr = [NSAttributedString attributedStringWithAttachment:attch]; [attributedStr insertAttributedString:attributedImageStr atIndex:0]; _label.attributedText = attributedStr; // 设置label的高度 CGSize attributeStrSize = [attributedStr boundingRectWithSize:CGSizeMake(SCREEN_WIDTH - 30, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil].size; // 计算出cell的高度 _label.frame = CGRectMake(15, 16, SCREEN_WIDTH - 30, attributeStrSize.height); }else{ _label.textColor = [UIColor colorWithRed:46/255.0 green:46/255.0 blue:46/255.0 alpha:1.0]; _label.font = [UIFont fontWithName:@"PingFangSC-Regular" size:16]; _label.text = _model.content; // 设置label的高度 NSDictionary *dic = @{NSFontAttributeName:[UIFont fontWithName:@"PingFangSC-Regular" size:16]}; CGSize labelSize = [_model.content boundingRectWithSize:CGSizeMake(SCREEN_WIDTH - 30, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:dic context:nil].size; _label.frame = CGRectMake(15, 16, SCREEN_WIDTH - 30, labelSize.height); } // 设置cell的frame CGRect cellFrame = self.frame; cellFrame.size.height = CGRectGetMaxY(_label.frame) + 16; self.frame = cellFrame; } @end

接着,我们需要在控制器中得到cell的高度,并利用代理进行设置。 具体代码如下:

#pragma mark -tableview的代理 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //指定cellIdentifier为自定义的cell static NSString *CellIdentifier = @"Cell"; //自定义cell类 GCIWantRecieveCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[GCIWantRecieveCell alloc] initWithReuseIdentifier:CellIdentifier]; } cell.model = _recieveBoxArrs[indexPath.row]; return cell; } -(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return _recieveBoxArrs.count; } -(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView { return 1; } //在这个函数中获取相应的cell,返回cell的高度 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { GCIWantRecieveCell *cell = (GCIWantRecieveCell *)[self tableView:_mainTableView cellForRowAtIndexPath:indexPath]; return cell.frame.size.height; }

如果cell中还有其他的子控件,也可以按照这种方法,当然还有其他几种cell的高度自适应方法,例如sunny大神的一篇帖子sunny的博客。请多多交流

转载请注明原文地址: https://www.6miu.com/read-250338.html

最新回复(0)