自适应单元格
2018-12-17 本文已影响10人
ForzaJuven
高度自适应单元格
TableViewCell.h文件
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
static float detailDescriptionCellHeight = 110.f;
@interface DetailDescriptionCell : UITableViewCell
@property (nonatomic, copy) NSString *carModelName;//车辆名称
@property (nonatomic, assign) NSInteger amount; //库存数
@property (nonatomic, assign) float price; //售价
@property (nonatomic, assign) float salePrice; //建议售价
@property (nonatomic, assign) float cellHeight;
- (void)setDataWithCarModelName:(NSString *)carModelName Amount:(NSInteger)amount Price:(float)price SalePrice:(float)salePrice;
+ (DetailDescriptionCell *)newCellWithTableView:(UITableView *)tableView IndexPath:(NSIndexPath *)indexPath;
@end
NS_ASSUME_NONNULL_END
TableViewCell.m文件
#import "DetailDescriptionCell.h"
@interface DetailDescriptionCell ()
@property (nonatomic, strong) UILabel *carNameLabel;
@property (nonatomic, strong) UILabel *amountLabel;
@property (nonatomic, strong) UILabel *priceLabel;
@property (nonatomic, strong) UILabel *salePriceLabel;
@property (nonatomic, assign) CGSize carNameSize;
@property (nonatomic, assign) CGSize amountSize;
@property (nonatomic, assign) CGSize priceSize;
@property (nonatomic, assign) CGSize salePriceSize;
@end
@implementation DetailDescriptionCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
[self setDefaultData];
[self createUI];
}
return self;
}
+ (DetailDescriptionCell *)newCellWithTableView:(UITableView *)tableView IndexPath:(nonnull NSIndexPath *)indexPath{
static NSString * cellID = @"DetailDescriptionCell";
DetailDescriptionCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (!cell) {
cell = [[DetailDescriptionCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return cell;
}
#pragma mark - SetData
#pragma mark -
- (void)setDefaultData{
_carModelName = @"";
_amount = 0;
_price = 0.f;
_salePrice = 0.f;
_cellHeight = 110.f;
self.carNameSize = CGSizeZero;
self.amountSize = CGSizeZero;
self.priceSize = CGSizeZero;
self.salePriceSize = CGSizeZero;
}
- (void)setCarModelName:(NSString *)carModelName{
[self refreshCarModelName:carModelName];
[self cellNeedUpdateConstraints];
}
- (void)setAmount:(NSInteger)amount{
[self refreshAmount:amount];
[self cellNeedUpdateConstraints];
}
- (void)setPrice:(float)price{
[self refreshPrice:price];
[self cellNeedUpdateConstraints];
}
- (void)setSalePrice:(float)salePrice{
[self refreshSalePrice:salePrice];
[self cellNeedUpdateConstraints];
}
- (void)setDataWithCarModelName:(NSString *)carModelName Amount:(NSInteger)amount Price:(float)price SalePrice:(float)salePrice{
[self refreshCarModelName:carModelName];
[self refreshAmount:amount];
[self refreshPrice:price];
[self refreshSalePrice:salePrice];
[self cellNeedUpdateConstraints];
}
- (void)refreshCarModelName:(NSString *)carModelName{
if (STRING_IS_NIL(carModelName)) {
_carModelName = @"";
}else{
_carModelName = carModelName;
}
self.carNameLabel.text = _carModelName;
self.carNameSize = [PublicClass getSizeWithString:self.carModelName withFont:self.carNameLabel.font withLimitWidth:SCREEN_WIDTH-20];
}
- (void)refreshAmount:(NSInteger)amount{
_amount = amount;
self.amountLabel.text = [NSString stringWithFormat:@"库存%ld辆",(long)amount];
self.amountSize = [PublicClass getSizeWithString:self.amountLabel.text withFont:self.amountLabel.font withLimitWidth:SCREEN_WIDTH-24];
}
- (void)refreshPrice:(float)price{
_price = price;
NSString *priceStr = [NSString stringWithFormat:@"%0.2f",_price];
NSString *totalStr = [NSString stringWithFormat:@"%@万元",priceStr];
NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:totalStr];
[attStr addAttribute:NSFontAttributeName
value:[UIFont mediumFontWithSize:25]
range:[totalStr rangeOfString:totalStr]];
[attStr addAttribute:NSFontAttributeName
value:[UIFont boldSystemFontOfSize:30]
range:[totalStr rangeOfString:priceStr]];
[attStr addAttribute:NSForegroundColorAttributeName
value:CL_BLUE
range:[totalStr rangeOfString:totalStr]];
self.priceLabel.attributedText = attStr;
self.priceSize = [PublicClass getSizeWithAttributedString:self.priceLabel.attributedText withLimitWidth:250];
}
- (void)refreshSalePrice:(float)salePrice{
_salePrice = salePrice;
NSString *priceStr = [NSString stringWithFormat:@"%0.2f",_salePrice];
NSString *totalStr = [NSString stringWithFormat:@"建议售价:%@万",priceStr];
NSMutableAttributedString *attStr = [[NSMutableAttributedString alloc] initWithString:totalStr];
[attStr addAttribute:NSFontAttributeName
value:[UIFont mediumFontWithSize:15]
range:[totalStr rangeOfString:totalStr]];
[attStr addAttribute:NSFontAttributeName
value:[UIFont boldSystemFontOfSize:15]
range:[totalStr rangeOfString:priceStr]];
[attStr addAttribute:NSForegroundColorAttributeName
value:CL_4C
range:[totalStr rangeOfString:totalStr]];
self.salePriceLabel.attributedText = attStr;
self.salePriceSize = [PublicClass getSizeWithAttributedString:self.salePriceLabel.attributedText withLimitWidth:200];
}
#pragma mark - LayoutUI
#pragma mark -
- (void)cellNeedUpdateConstraints{
self.cellHeight = 15 + self.carNameSize.height + 13 + 20 + 13 + self.priceSize.height + 11;
[self setNeedsUpdateConstraints];
[self updateConstraints];
}
+ (BOOL)requiresConstraintBasedLayout{
return YES;
}
- (void)updateConstraints{
[super updateConstraints];
[self.carNameLabel mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.offset(12);
make.top.offset(15);
make.width.offset(self.carNameSize.width+4);
make.height.offset(self.carNameSize.height);
}];
[self.amountLabel mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.offset(12);
make.top.equalTo(self.carNameLabel.mas_bottom).offset(13);
make.height.offset(20);
make.width.offset(self.amountSize.width+6);
}];
[self.priceLabel mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.offset(12);
make.top.equalTo(self.amountLabel.mas_bottom).offset(13);
make.width.offset(self.priceSize.width+4);
make.height.offset(self.priceSize.height);
}];
[self.salePriceLabel mas_updateConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.priceLabel.mas_right).offset(14);
make.bottom.equalTo(self.priceLabel.mas_bottom);
make.width.offset(self.salePriceSize.width+4);
make.height.offset(self.salePriceSize.height);
}];
}
- (void)createUI{
self.carNameLabel = [UILabel new];
[self.carNameLabel setNumberOfLines:0];
[self.carNameLabel setBackgroundColor:CL_C1];
[self.carNameLabel setFont:[UIFont mediumFontWithSize:16]];
[self.carNameLabel setTextColor:CL_2C];
[self.carNameLabel setLineBreakMode:NSLineBreakByTruncatingTail];
self.amountLabel = [UILabel new];
[self.amountLabel.layer setBorderWidth:1];
[self.amountLabel.layer setBorderColor:CL_A1.CGColor];
[self.amountLabel setBackgroundColor:CL_C1];
[self.amountLabel setFont:[UIFont mediumFontWithSize:13]];
[self.amountLabel setTextColor:CL_A1];
[self.amountLabel setLineBreakMode:NSLineBreakByTruncatingTail];
[self.amountLabel setTextAlignment:NSTextAlignmentCenter];
self.priceLabel = [UILabel new];
[self.priceLabel setBackgroundColor:CL_C1];
[self.priceLabel setFont:[UIFont mediumFontWithSize:16]];
[self.priceLabel setTextColor:COLOR_TINK_BLUE];
self.salePriceLabel = [UILabel new];
[self.salePriceLabel setBackgroundColor:CL_C1];
[self.salePriceLabel setFont:[UIFont mediumFontWithSize:16]];
[self.salePriceLabel setTextColor:CL_4C];
[self.contentView addSubview:self.carNameLabel];
[self.contentView addSubview:self.amountLabel];
[self.contentView addSubview:self.priceLabel];
[self.contentView addSubview:self.salePriceLabel];
[self cellNeedUpdateConstraints];
}
@end
单元格的使用与高度设置
if (indexPath.row == CarInfoCellType_carInfo) {
DetailDescriptionCell *cell = [DetailDescriptionCell newCellWithTableView:tableView IndexPath:indexPath];
[cell setDataWithCarModelName:_model.carModelName
Amount:[_model.amount integerValue]
Price:[_model.price floatValue]
SalePrice:[_model.predictPrice floatValue]];
//保存单元格高度解决
self.carInfoCellHeight = cell.cellHeight;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == CarInfoCellType_carInfo) {
return _carInfoCellHeight;
}
}
图片高度自适应单元格
TableViewCell.h文件
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@protocol CarImageCellProtocol <NSObject>
//在图片加载完成后计算并返回单元格高度
//为了解决cellForRowAtIndexPath中设置完cell属性后,heightForRowAtIndexPath中获取到的cell还未更新的问题
//在方法实现中对单元格高度进行保存并调用reloadRowsAtIndexPaths刷新高度
- (void)carImageLoadCompleteWithIndexPath:(NSIndexPath *)indexpath cellHeight:(float)cellHeight;
@end
@interface CarImageCell : UITableViewCell
@property (nonatomic, copy) NSString *imagePath;
@property (nonatomic, weak) id <CarImageCellProtocol> delegate;
@property (nonatomic, assign) float cellHeight;
- (void)setDataWithImagePath:(NSString *)imagePath;
+ (CarImageCell *)newCellWithTableView:(UITableView *)tableView IndexPath:(NSIndexPath *)indexPath;
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier IndexPath:(NSIndexPath *)indexPath;
@end
NS_ASSUME_NONNULL_END
TableViewCell.m文件
#import "CarImageCell.h"
static float maxImageHeight = 250.0f;
@interface CarImageCell ()
@property (nonatomic, strong) UIImageView *carImage;
@property (nonatomic, strong) NSIndexPath *cellIndexPath;
@end
@implementation CarImageCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier IndexPath:(nonnull NSIndexPath *)indexPath{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.cellIndexPath = indexPath;
[self createUI];
}
return self;
}
+ (CarImageCell *)newCellWithTableView:(UITableView *)tableView IndexPath:(nonnull NSIndexPath *)indexPath{
static NSString * cellID = @"CarImageCell";
CarImageCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (!cell) {
cell = [[CarImageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID IndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return cell;
}
#pragma mark - SetData
#pragma mark -
- (void)setImagePath:(NSString *)imagePath{
[self refreshDataWithImagePath:imagePath];
}
- (void)setDataWithImagePath:(NSString *)imagePath{
[self refreshDataWithImagePath:imagePath];
}
- (void)refreshDataWithImagePath:(NSString *)imagePath{
_imagePath = imagePath;
//使用sd_setImageWithURL: placeholderImage :completed:方法在图片加载完成后对单元格操作
[self.carImage sd_setImageWithURL:[NSURL URLWithString:imagePath] placeholderImage:[UIImage imageNamed:@"icon_imageplaceholder"] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
self.cellHeight = [self calculationCellHeightWithImageSize:image.size];
if (self.delegate && [self.delegate respondsToSelector:@selector(carImageLoadCompleteWithIndexPath:cellHeight:)]) {
[self.delegate carImageLoadCompleteWithIndexPath:self.cellIndexPath cellHeight:self.cellHeight];
self.carImage.frame = CGRectMake(12, 10, SCREEN_WIDTH-24, self.cellHeight-10);
}
}];
}
#pragma mark - LayoutUI
#pragma mark -
- (void)createUI{
//创建carImage并设置placeholder
self.cellHeight = [self calculationCellHeightWithImageSize:CGSizeMake(230, 166)];
self.carImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"icon_imageplaceholder"]];
self.carImage.frame = CGRectMake(12, 10, SCREEN_WIDTH-24, self.cellHeight-10);
self.carImage.contentMode = UIViewContentModeScaleAspectFill;
self.carImage.clipsToBounds = YES;
[self.contentView addSubview:self.carImage];
}
#pragma mark - PrivateMethod
/**
* 根据图片size计算单元格高度
*/
- (float)calculationCellHeightWithImageSize:(CGSize)size{
float imageWidth = SCREEN_WIDTH-24.0f;//宽度固定
float imageHeight = imageWidth/size.width*size.height;//根据宽度计算高度
//限制最大高度
if (imageHeight>maxImageHeight) {
imageHeight = maxImageHeight;
}
//10为单元格间隔
imageHeight += 10;
return imageHeight;
}
@end
代理的实现与高度设置
#pragma mark - CarImageCellProtocol
#pragma mark -
- (void)carImageLoadCompleteWithIndexPath:(NSIndexPath *)indexpath cellHeight:(float)cellHeight{
//保存高度数据
[self.carImageCellHeight setObject:[NSNumber numberWithFloat:cellHeight] forKey:[NSString stringWithFormat:@"%d",(int)indexpath.row]];
//刷新单元格
[_attachView refreshTableViewCellWithIndexPath:indexpath];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
switch (indexPath.section) {
case SectionType_carInfo:{
if (indexPath.row == CarInfoCellType_banner) {
return DetailBannerCellHeight;
}
if (indexPath.row == CarInfoCellType_carInfo) {
return _carInfoCellHeight;
}
if (indexPath.row == CarInfoCellType_carConfig) {
return DetailConfigCellHeight;
}
}
break;
case SectionType_carConfig:{
return detailConfigDetailCellHeight;
}
break;
//根据保存的单元格高度设置单元格
case SectionType_carImage:{
return [[self.carImageCellHeight objectForKey:[NSString stringWithFormat:@"%d",(int)indexPath.row]] floatValue];
}
break;
default:
return 0;
break;
}
return 0;
}