自适应单元格

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;
}
上一篇 下一篇

猜你喜欢

热点阅读