直接上代码;
1. 创建一个类IDOCellModel,继承NSObject,里面的属性如下:
@interface IDOCellModel : NSObject
/**
cell 的唯一标示
*/
@property (nonatomic, copy) NSString *key;
/**
cell 的高度
*/
@property (nonatomic, assign) CGFloat rowHeight;
/**
类型,这个参数主要是用于同一中类型的cell,但是传入不相同的数据
*/
@property (nonatomic, assign) NSInteger type;
/**
是否在处于加载中的状态,这种情况一般是使用在多个接口加载数据的时候,不同的cell显示加载情况
*/
@property (nonatomic, assign) BOOL isLoading;
/**
点击cell时的目标控制器或者view,主要是用于跳转或者弹框
*/
@property (nonatomic, strong) id target;
/**
cell 所需的数据
*/
@property (nonatomic, strong) id data;
/**
多个cell的数组,一般主要使用在同一个section里面,存在有不同的cell的情况
*/
@property (nonatomic, strong) NSArray
@end
2. 创建一个IDOTableViewMulCellViewModel,继承NSObject
#import
#import "IDOCellModel.h"
#import "IDOHomeStepCell.h"
#import "IDOHomeHeartCell.h"
#import "IDOHomeSportCell.h"
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, IDOTableViewMulCelHeartType) {
IDOTableViewMulCelHeartTypeOne =1,
IDOTableViewMulCelHeartTypetwo =2,
IDOTableViewMulCelHeartTypeThree =3,
IDOTableViewMulCelHeartTypeFour =4
};
@interface IDOTableViewMulCellViewModel : NSObject
/**
返回的数据模型
*/
@property (nonatomic, strong) IDOCellModel *cellModel;
#pragma mark- 网络加载数据
- (void)loadDataCompeleter:(void(^)(BOOLresult,id_Nullableobj))compeleter;
#pragma mark - tableView相关的
- (NSInteger)numberOfTableViewSection;
- (NSInteger)numberOfRowInSection:(NSInteger)section;
- (IDOBaseTableViewCell*)cellWithTableView:(UITableView*)tableViewindexPath:(NSIndexPath*)indexPath;
- (CGFloat)cellHeightWithIndexPath:(NSIndexPath *)indexPath;
#pragma mark- 根据下标读取数据
/**
获取数据
*/
- (void)getDataWithSection:(NSInteger)sectionrow:(NSInteger)row;
@end
#import "IDOTableViewMulCellViewModel.h"
#define cellHeightDicKey(section,row) ([NSString stringWithFormat:@"%ld_%ld",section,row])
@interface IDOTableViewMulCellViewModel ()
/**
数据源
*/
@property (nonatomic, strong) NSMutableArray *datas;
@property (nonatomic, strong) NSMutableDictionary *heightDict;
@end
@implementation IDOTableViewMulCellViewModel
- (instancetype)init{
if(self= [superinit]) {
self.datas = [NSMutableArray array];
self.heightDict = [NSMutableDictionary dictionary];
[selfinitData];
}
return self;
}
/**
默认的数据值
*/
- (void)initData{
IDOCellModel*sheartCellModel = [[IDOCellModelalloc]init];
sheartCellModel.key=NSStringFromClass([IDOHomeHeartCellclass]);
sheartCellModel.rowHeight=150;
sheartCellModel.type = IDOTableViewMulCelHeartTypeOne;
[self.datasaddObject:sheartCellModel];
IDOCellModel*stepCellModel = [[IDOCellModelalloc]init];
stepCellModel.key=NSStringFromClass([IDOHomeStepCellclass]);
stepCellModel.rowHeight=200;
[self.datasaddObject:stepCellModel];
IDOCellModel*heartCellModel = [[IDOCellModelalloc]init];
heartCellModel.key=NSStringFromClass([IDOHomeHeartCellclass]);
heartCellModel.rowHeight=150;
heartCellModel.type = IDOTableViewMulCelHeartTypetwo;
[self.datasaddObject:heartCellModel];
IDOCellModel*stepsCellModel = [[IDOCellModelalloc]init];
stepsCellModel.key=NSStringFromClass([IDOHomeSportCellclass]);
IDOCellModel*subStepCellModel1 = [[IDOCellModelalloc]init];
subStepCellModel1.type = IDOTableViewMulCelHeartTypeOne;
subStepCellModel1.key=NSStringFromClass([IDOHomeSportCellclass]);
subStepCellModel1.rowHeight=60;
IDOCellModel*subStepCellModel2 = [[IDOCellModelalloc]init];
subStepCellModel2.type = IDOTableViewMulCelHeartTypetwo;
subStepCellModel2.rowHeight=60;
subStepCellModel2.key=NSStringFromClass([IDOHomeSportCellclass]);
IDOCellModel*subStepCellModel3 = [[IDOCellModelalloc]init];
subStepCellModel3.type = IDOTableViewMulCelHeartTypeThree;
subStepCellModel3.rowHeight=60;
subStepCellModel3.key=NSStringFromClass([IDOHomeSportCellclass]);
IDOCellModel*subStepCellModel4 = [[IDOCellModelalloc]init];
subStepCellModel4.type = IDOTableViewMulCelHeartTypeThree;
subStepCellModel4.rowHeight=60;
subStepCellModel4.key=NSStringFromClass([IDOHomeSportCellclass]);
stepsCellModel.rowItems= [NSArrayarrayWithObjects:subStepCellModel1,subStepCellModel2,subStepCellModel3,subStepCellModel4,nil];
[self.datasaddObject:stepsCellModel];
}
#pragma mark- 网络加载
- (void)loadDataCompeleter:(void(^)(BOOLresult,id_Nullableobj))compeleter{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[selfloadStepData];
[selfloadHeartData];
[selfloadsHeartData];
[selfloadSubStepsData];
dispatch_async(dispatch_get_main_queue(), ^{
if(compeleter) {
compeleter(YES,nil);
}
});
});
});
}
- (void)loadHeartData{
NSString *currentKey = [NSString stringWithFormat:@"%@%ld",NSStringFromClass([IDOHomeHeartCell class]),(long)IDOTableViewMulCelHeartTypetwo];
IDOCellModel *sModel = [self getCellModelWithKey:currentKey withDatas:self.datas];
sModel.data=@[@"120",@"90"];
[self updateDatasWithCellModel:sModel datas:self.datas];
}
- (void)loadsHeartData{
NSString *currentKey = [NSString stringWithFormat:@"%@%ld",NSStringFromClass([IDOHomeHeartCell class]),(long)IDOTableViewMulCelHeartTypeOne];
IDOCellModel *sModel = [self getCellModelWithKey:currentKey withDatas:self.datas];
sModel.data=@[@"10",@"30"];
[self updateDatasWithCellModel:sModel datas:self.datas];
}
- (void)loadStepData{
NSString *currentKey = [NSString stringWithFormat:@"%@0",NSStringFromClass([IDOHomeStepCell class])];
IDOCellModel *sModel = [self getCellModelWithKey:currentKey withDatas:self.datas];
sModel.data=@[@"500",@"20000"];
[self updateDatasWithCellModel:sModel datas:self.datas];
}
- (void)loadSubStepsData{
NSString *currentKey = [NSString stringWithFormat:@"%@0",NSStringFromClass([IDOHomeSportCell class])];
IDOCellModel *sModel = [self getCellModelWithKey:currentKey withDatas:self.datas];
NSString *subStepModelOneKey = [NSString stringWithFormat:@"%@%ld",NSStringFromClass([IDOHomeSportCell class]),IDOTableViewMulCelHeartTypeOne];
IDOCellModel*subStepModelone = [selfgetCellModelWithKey:subStepModelOneKeywithDatas:sModel.rowItems];
subStepModelone.data = @[@"当前运动了200步当前运动了200步当前运动了200步当前运动了200步当前运动了200步当前运动了200步当前运动了200步当前运动了200步当前运动了200步当前运动了200步当前运动了200步当前运动了200步当前运动了200步"];
NSString *subStepModelTwoKey = [NSString stringWithFormat:@"%@%ld",NSStringFromClass([IDOHomeSportCell class]),IDOTableViewMulCelHeartTypetwo];
IDOCellModel*subStepModeltwo = [selfgetCellModelWithKey:subStepModelTwoKeywithDatas:sModel.rowItems];
subStepModeltwo.data=@[@"好的,就200"];
NSMutableArray*rowItems = [sModel.rowItemsmutableCopy];
[selfupdateDatasWithCellModel:subStepModelonedatas:rowItems];
[selfupdateDatasWithCellModel:subStepModeltwodatas:rowItems];
sModel.rowItems= [rowItemscopy];
[self updateDatasWithCellModel:sModel datas:self.datas];
}
#pragma mark- 数据的更新及查询
//更新数据
- (void)updateDatasWithCellModel:(IDOCellModel*)cellModeldatas:(NSMutableArray*)datas{
if(cellModel ==nil) {
return;
}
//在这里要使用,key和type的原因是因为可能会出现同样key但是现实不同类型的数据
NSString*currentKey = [NSStringstringWithFormat:@"%@%ld",cellModel.key,(long)cellModel.type];
//获取下标
NSIntegerindex = -1;
for(IDOCellModel*cModelindatas) {
NSString*ckey = [NSStringstringWithFormat:@"%@%ld",cModel.key,(long)cModel.type];
if([currentKeyisEqualToString:ckey]) {
index = [datasindexOfObject:cModel];
break;
}
}
if(index != -1) {
[datasreplaceObjectAtIndex:indexwithObject:cellModel];
}
}
- (IDOCellModel *)getCellModelWithKey:(NSString *)key withDatas:(NSArray *)datas{
IDOCellModel*currentModel =nil;
if(datas.count==0|| datas ==nil) {
returncurrentModel;
}
for(IDOCellModel*cModelindatas) {
NSString*ckey = [NSStringstringWithFormat:@"%@%ld",cModel.key,(long)cModel.type];
if([keyisEqualToString:ckey]) {
currentModel = cModel;
break;;
}
}
returncurrentModel;
}
#pragma mark- 把数据设置到View
- (NSInteger)numberOfTableViewSection{
return self.datas.count;
}
- (NSInteger)numberOfRowInSection:(NSInteger)section{
if(section <0|| section >self.datas.count-1) {
return0;
}
IDOCellModel*cellModel =self.datas[section];
returncellModel.rowItems.count>0? cellModel.rowItems.count:1;
}
- (IDOBaseTableViewCell*)cellWithTableView:(UITableView*)tableViewindexPath:(NSIndexPath*)indexPath{
IDOCellModel*cellModel = [selfdataWithSection:indexPath.sectionrow:indexPath.row];
IDOBaseTableViewCell*cell = [tableViewdequeueReusableCellWithIdentifier:cellModel.key];
if(!cell) {
Classcls =NSClassFromString(cellModel.key);
cell = [[clsalloc]init];
}
cell.data = self.cellModel.data;
NSString*key =cellHeightDicKey((long)indexPath.section,(long)indexPath.row);
if(cell.cellHeight>0) {
CGSize size = [cell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
[self.heightDictsetValue:@(size.height)forKey:key];
}else{
[self.heightDictsetValue:@(cellModel.rowHeight)forKey:key];
}
returncell;
}
- (CGFloat)cellHeightWithIndexPath:(NSIndexPath *)indexPath{
NSString*key =cellHeightDicKey((long)indexPath.section,(long)indexPath.row);
return [[self.heightDict valueForKey:key] floatValue];
}
//给外面调用数据
- (void)getDataWithSection:(NSInteger)sectionrow:(NSInteger)row{
[selfdataWithSection:sectionrow:row];
}
#pragma mark- 内部处理的数据方法
- (IDOCellModel*)dataWithSection:(NSInteger)sectionrow:(NSInteger)row{
if(section <0|| section >self.datas.count-1) {
returnnil;
}
IDOCellModel*cellModel =self.datas[section];
if(cellModel.rowItems.count==0|| cellModel.rowItems==nil) {
self.cellModel= cellModel;
}else{
IDOCellModel*subCellModel = cellModel.rowItems[row];
self.cellModel= subCellModel;
}
return self.cellModel;
}
3. 创建一个基础的cell,IDOBaseTableViewCell;
@interface IDOBaseTableViewCell : UITableViewCell
/**
传入的值,根据自己的cell 的情况传入不同的值,需要子类进行重写
*/
@property (nonatomic, strong) id data;
/**
根据传入的数据,自动获取cell的高度,也是要在子类中获取
*/
@property (nonatomic, assign) CGFloat cellHeight;
/**
cell 的标识
*/
+ (NSString *)cellReuseIdentifier;
/**
设置cell 的子控件,需要子类实现
*/
- (void)configCellSubView;
@end
其他的子类的cell继承这个基类进行创建
4. 把IDOTableViewMulCellViewModel 导入到IDOTableViewMulCellDemoViewController中;
#import "IDOTableViewMulCellDemoViewController.h"
#import "IDOTableViewMulCellViewModel.h"
@interface IDOTableViewMulCellDemoViewController ()
@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) IDOTableViewMulCellViewModel *viewModel;
@end
@implementation IDOTableViewMulCellDemoViewController
- (UITableView *)tableView{
if(!_tableView) {
_tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
[self.viewaddSubview:_tableView];
[_tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(0);
make.top.mas_equalTo(self.ido_naviBarBottomToTopHeight);
make.width.mas_equalTo(kScreenWidth);
make.height.mas_equalTo(kScreenHeight - self.ido_naviBarBottomToTopHeight - IDO_TABBAR_HEIGHT);
}];
_tableView.delegate=self;
_tableView.dataSource=self;
_tableView.tableFooterView = [UIView new];
}
return _tableView;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.viewModel = [[IDOTableViewMulCellViewModel alloc] init];
self.tableView.hidden=NO;
// Do any additional setup after loading the view.
WEAKSELF
[self.viewModelloadDataCompeleter:^(BOOLresult,id _Nullableobj) {
[weakSelf.tableViewreloadData];
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [self.viewModel numberOfTableViewSection];
}
- (NSInteger)tableView:(UITableView*)tableViewnumberOfRowsInSection:(NSInteger)section{
return [self.viewModel numberOfRowInSection:section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
IDOBaseTableViewCell *cell = [self.viewModel cellWithTableView:tableView indexPath:indexPath];
returncell;
}
- (CGFloat)tableView:(UITableView*)tableViewheightForRowAtIndexPath:(NSIndexPath*)indexPath{
return [self.viewModel cellHeightWithIndexPath:indexPath];
}