iOS UITableView 中实现多种cell的方案

直接上代码;

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 *rowItems;

@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];

}

你可能感兴趣的:(iOS UITableView 中实现多种cell的方案)