iOS-通过Model控制UITableView

2020-01-03  本文已影响0人  _LZZ_

想必大家在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时不方便;

上一篇 下一篇

猜你喜欢

热点阅读