想必大家在iOS开发都有遇到过在一个UITableView中展示各式各样UITableViewCell,导致在UITableViewDelegate、UITableViewDataSource中的代码过于臃肿。本文也是想着分享本人在工作的一些拙见,还请大家不喜勿喷;
一、源代码
通过Model控制UITableView主要分为以下两个类文件:
1、控制UITableView section的TableViewSectionModel
TableViewSectionModel.h文件,可根据需要自行填充
#import "TableViewRowModel.h"
@interface TableViewSectionModel : NSObject
@property (nonatomic,assign) BOOL hasHeader; //是否有tableviewHeaderView
@property (nonatomic,assign) CGFloat headerHeight; //tableviewHeaderView高度
@property (nonatomic,copy) NSString *headerViewName; // tableviewHeaderView名称
@property (nonatomic,strong) id headerViewDataSource; // tableviewHeaderView数据
@property (nonatomic,assign) BOOL hasFooter; //是否有tableviewFooterView
@property (nonatomic,assign) CGFloat footerHeight; //tableviewFooterView高度
@property (nonatomic,copy) NSString *footerViewName; // tableviewFooterView名称
@property (nonatomic,strong) id footerViewDataSource; // tableviewFooterView数据
@property (nonatomic,copy) NSArray <TableViewRowModel *> *rows;// 行模型
@end
TableViewSectionModel.m文件,我这里只设置了初始化属性,可根据需要自行填充
@implementation TableViewSectionModel
-(instancetype)init{
if (self = [super init]) {
[self _initValue];
}
return self;
}
-(void)_initValue{
self.hasHeader = NO;
self.headerHeight = CGFLOAT_MIN;
self.headerViewName = @"";
self.hasFooter = NO;
self.footerHeight = CGFLOAT_MIN;
self.footerViewName = @"";
self.rows = [NSArray array];
}
@end
2、控制UITableView row的TableViewRowModel
TableViewRowModel.h文件,可根据需要自行填充
@interface TableViewRowModel : NSObject
@property (nonatomic,copy) NSString *cellName;//cell名称
@property (nonatomic,assign) CGFloat cellHeight;//cell高度
@property (nonatomic,strong) id cellModel;//cell数据模型
@end
TableViewRowModel.m文件中没有编写任何内容,所有这里我就没有展示
二、实际应用
假设实际应用UITableView中有OneCell、TwoCell、OtherCell跟OneSectionHeaderView与TwoSectionHeaderView,这些文件中只有一个函数
-(void)reloadWithModel:(id)model;
ViewController中代码如下:
#import "ViewController.h"
#import "OneCell.h"
#import "TwoCell.h"
#import "OtherCell.h"
#import "OneSectionHeaderView.h"
#import "TwoSectionHeaderView.h"
#import "TableViewSectionModel.h"
@interface ViewController () <UITableViewDataSource,UITableViewDelegate>
@property (nonatomic,strong) UITableView *tableView;
@property (nonatomic,strong) NSMutableArray <TableViewSectionModel *>*dataSource;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self _addSubviews];
//假设是在请求数据
[self _loadDataWithResults:nil];
}
-(void)_loadDataWithResults:(NSDictionary *)results{
//这里的代码我一般放在处理JSON数据的地方
{
//设置Section Header
TableViewSectionModel *sectionModel = [[TableViewSectionModel alloc] init];
sectionModel.hasHeader = YES;
sectionModel.headerHeight = 68.0f;
sectionModel.headerViewName = @"OneSectionHeaderView";
sectionModel.headerViewDataSource = [NSObject new];
//设置Section Footer,与Header用法一致,我这里只设置了一个高度
sectionModel.footerHeight = 8.0f;
//设置Rows
NSMutableArray *rows = [NSMutableArray array];
for (NSInteger i = 0; i < 5; i ++) {
TableViewRowModel *rowModel = [[TableViewRowModel alloc] init];
rowModel.cellHeight = 100.0f;
rowModel.cellName = @"OneCell";
rowModel.cellModel = [NSObject new];
[rows addObject:rowModel];
}
sectionModel.rows = rows.copy;
[self.dataSource addObject:sectionModel];
}
{
//设置Section Header
TableViewSectionModel *sectionModel = [[TableViewSectionModel alloc] init];
sectionModel.hasHeader = YES;
sectionModel.headerHeight = 168.0f;
sectionModel.headerViewName = @"TwoSectionHeaderView";
sectionModel.headerViewDataSource = [NSObject new];
//设置Section Footer,与Header用法一致,我这里只设置了一个高度
sectionModel.footerHeight = 8.0f;
//设置Rows
TableViewRowModel *rowModel = [[TableViewRowModel alloc] init];
rowModel.cellHeight = 50.0f;
rowModel.cellName = @"TwoCell";
rowModel.cellModel = [NSObject new];
sectionModel.rows = @[rowModel];
[self.dataSource addObject:sectionModel];
}
{
TableViewSectionModel *sectionModel = [[TableViewSectionModel alloc] init];
//设置Section Footer,与Header用法一致,我这里只设置了一个高度
sectionModel.footerHeight = 8.0f;
//设置Rows
NSMutableArray *rows = [NSMutableArray array];
for (NSInteger i = 0; i < 5; i ++) {
TableViewRowModel *rowModel = [[TableViewRowModel alloc] init];
rowModel.cellHeight = 130.0f;
rowModel.cellName = @"OtherCell";
rowModel.cellModel = [NSObject new];
[rows addObject:rowModel];
}
sectionModel.rows = rows.copy;
[self.dataSource addObject:sectionModel];
}
[self.tableView reloadData];
}
#pragma mark - UITableViewDataSource
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return self.dataSource.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataSource[section].rows.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
TableViewRowModel *rowModel = self.dataSource[indexPath.section].rows[indexPath.row];
if ([rowModel.cellName isEqual:@"OneCell"]) {
OneCell *cell = [tableView dequeueReusableCellWithIdentifier:rowModel.cellName];
if (cell == nil) {
cell = [[OneCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:rowModel.cellName];
}
[cell reloadWithModel:rowModel.cellModel];
return cell;
}else if ([rowModel.cellName isEqual:@"TwoCell"]) {
TwoCell *cell = [tableView dequeueReusableCellWithIdentifier:rowModel.cellName];
if (cell == nil) {
cell = [[TwoCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:rowModel.cellName];
}
[cell reloadWithModel:rowModel.cellModel];
return cell;
}else if ([rowModel.cellName isEqual:@"OtherCell"]) {
OtherCell *cell = [tableView dequeueReusableCellWithIdentifier:rowModel.cellName];
if (cell == nil) {
cell = [[OtherCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:rowModel.cellName];
}
[cell reloadWithModel:rowModel.cellModel];
return cell;
}
return [UITableViewCell new];
}
#pragma mark - UITableViewDelegate
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return self.dataSource[indexPath.section].rows[indexPath.row].cellHeight;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
return self.dataSource[section].headerHeight;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return self.dataSource[section].footerHeight;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
TableViewSectionModel *sectionModel = self.dataSource[section];
if (sectionModel.hasHeader) {
if ([sectionModel.headerViewName isEqual:@"OneSectionHeaderView"]) {
OneSectionHeaderView *headerView = [[OneSectionHeaderView alloc] init];
headerView.frame = CGRectMake(0.0f, 0.0f, self.view.frame.size.width, sectionModel.headerHeight);
headerView.backgroundColor = [UIColor whiteColor];
[headerView reloadWithModel:sectionModel.headerViewDataSource];
return headerView;
}else if ([sectionModel.headerViewName isEqual:@"TwoSectionHeaderView"]) {
TwoSectionHeaderView *headerView = [[TwoSectionHeaderView alloc] init];
headerView.frame = CGRectMake(0.0f, 0.0f, self.view.frame.size.width, sectionModel.headerHeight);
headerView.backgroundColor = [UIColor whiteColor];
[headerView reloadWithModel:sectionModel.headerViewDataSource];
return headerView;
}
}
return nil;
}
#pragma mark - setter UI
-(void)_addSubviews{
[self.view addSubview:self.tableView];
}
#pragma mark - getter and setter
-(UITableView *)tableView{
if (_tableView == nil) {
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
_tableView.estimatedRowHeight = CGFLOAT_MIN;
_tableView.estimatedSectionHeaderHeight = CGFLOAT_MIN;
_tableView.estimatedSectionFooterHeight = CGFLOAT_MIN;
_tableView.dataSource = self;
_tableView.delegate = self;
}
return _tableView;
}
-(NSMutableArray<TableViewSectionModel *> *)dataSource{
if(_dataSource == nil){
_dataSource = [NSMutableArray array];
}
return _dataSource;
}
@end
页面呈现
image.png
三、优缺点
优点:结构更加清晰,代码轻微减少;
缺点:用户交互需要更新UI时不方便;
网友评论