自适应cell
2020-11-30 本文已影响0人
Silence_xl
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface AutoModel : NSObject
@property (copy, nonatomic) NSString *title;
@property (copy, nonatomic) NSString *content;
@property (strong, nonatomic) UIImage *avatar;
@property (assign, nonatomic) CGFloat cellHeight;// Cache
@end
NS_ASSUME_NONNULL_END
//========================================
#import "AutoModel.h"
@implementation AutoModel
@end
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@class AutoModel;
@interface AutoCell : UITableViewCell
- (void)setupData:(AutoModel *)autoModel;
@end
NS_ASSUME_NONNULL_END
//======================================
#import "AutoCell.h"
#import "AutoModel.h"
#import <Masonry/Masonry.h>
@interface AutoCell ()
@property (nonatomic, strong) UIImageView *avatarImageView;
@property (nonatomic, strong) UILabel *titleLabel;
@property (nonatomic, strong) UILabel *contentLabel;
@property (nonatomic, strong) AutoModel *autoModel;
@end
@implementation AutoCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self initView];
}
return self;
}
- (void)setupData:(AutoModel *)autoModel {
_autoModel = autoModel;
_avatarImageView.image = autoModel.avatar;
_titleLabel.text = autoModel.title;
_contentLabel.text = autoModel.content;
}
- (void)initView {
self.tag = 1000;
// Avatar头像
_avatarImageView = [UIImageView new];
[self.contentView addSubview:_avatarImageView];
[_avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.and.height.equalTo(@44);
make.left.and.top.equalTo(self.contentView).with.offset(4);
}];
// Title - 单行
_titleLabel = [UILabel new];
[self.contentView addSubview:_titleLabel];
[_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@22);
make.top.equalTo(self.contentView).with.offset(4);
make.left.equalTo(_avatarImageView.mas_right).with.offset(4);
make.right.equalTo(self.contentView).with.offset(-4);
}];
// 计算UILabel的preferredMaxLayoutWidth值,多行时必须设置这个值,否则系统无法决定Label的宽度
CGFloat preferredMaxWidth = [UIScreen mainScreen].bounds.size.width - 44 - 4 * 3; // 44 = avatar宽度,4 * 3为padding
_contentLabel = [UILabel new];
_contentLabel.numberOfLines = 0;
_contentLabel.preferredMaxLayoutWidth = preferredMaxWidth; // 多行时必须设置
[self.contentView addSubview:_contentLabel];
[_contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(_titleLabel.mas_bottom).with.offset(4);
make.left.equalTo(_avatarImageView.mas_right).with.offset(4);
make.right.equalTo(self.contentView).with.offset(-4);
make.bottom.equalTo(self.contentView).with.offset(-4);
}];
[_contentLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
}
@end
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end
//================================
#import "ViewController.h"
#import "AutoCell.h"
#import "AutoModel.h"
@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>
@property (strong, nonatomic) UITableView *tableView;
@property (strong, nonatomic) AutoCell *templateCell;
@property (nonatomic, strong) NSArray *data;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tableView];
[self generateData];
[_tableView reloadData];
}
- (UITableView *)tableView {
if (!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.estimatedRowHeight = 80.0f;
_tableView.rowHeight = UITableViewAutomaticDimension;
_tableView.sectionHeaderHeight = 0.0;
_tableView.sectionFooterHeight = 0.0;
_tableView.estimatedSectionHeaderHeight = 0.0;
_tableView.estimatedSectionFooterHeight = 0.0;
[_tableView registerClass:[AutoCell class] forCellReuseIdentifier:NSStringFromClass([AutoCell class])];
}
return _tableView;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _data.count;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
#ifdef IOS_8_NEW_FEATURE_SELF_SIZING
// iOS 8 的Self-sizing特性
return UITableViewAutomaticDimension;
#else
if (!_templateCell) {
_templateCell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([AutoCell class])];
_templateCell.tag = -1000; // For debug dealloc
}
// 获取对应的数据
AutoModel *autoModel = _data[indexPath.row];
// 判断高度是否已经计算过
if (autoModel.cellHeight <= 0) {
// 填充数据
[_templateCell setupData:autoModel];
// 根据当前数据,计算Cell的高度,注意+1
autoModel.cellHeight = [_templateCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + 0.5f;
NSLog(@"Calculate: %ld, height: %g", (long) indexPath.row, autoModel.cellHeight);
} else {
NSLog(@"Get cache: %ld, height: %g", (long) indexPath.row, autoModel.cellHeight);
}
return autoModel.cellHeight;
#endif
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
AutoCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([AutoCell class]) forIndexPath:indexPath];
[cell setupData:_data[indexPath.row]];
return cell;
}
#pragma mark - Private methods
// 生成数据
- (void)generateData {
NSMutableArray *tmpData = [NSMutableArray new];
for (int i = 0; i < 20; i++) {
AutoModel *autoModel = [AutoModel new];
autoModel.avatar = [UIImage imageNamed:[NSString stringWithFormat:@"bluefaces_%d", (i % 4) + 1]];
autoModel.title = [NSString stringWithFormat:@"Title: %d", i];
autoModel.content = [NSString stringWithFormat:@"第%d条数据 == %@",i,[self getRandomLengthStr]];
[tmpData addObject:autoModel];
}
_data = tmpData;
}
- (NSString *)getRandomLengthStr {
NSMutableString *str = [NSMutableString string];
for (NSInteger i = 0; i < (arc4random() % 50) + 10; i++) {
[str appendString:@"content-"];
}
return [str copy];
}
@end
