在项目中tableview
列表经常使用到,所以在创建视图时,我们会在每个使用到tableview
的页面创建tableview
并且实现代理方法,代理方法包括组数,行数,cell
返回,行高、头视图等。方法很多,每次都要重写这些代理方法,因此我们需要分离视图和这些代理方法,让代理方法成为公用部分。
实现过程
1、创建TableViewDataSource
类继承自NSObject
遵循UITableViewDataSource
协议,实现cell
的代理方法。通过block
将主要参数cell、model、indexPath
引出,在主视图中实现数据加载。
2、创建TableviewDelegate
类继承自NSObject
遵循UITableViewDelegate
协议,实现头视图、尾部视图、头视图高度、尾部视图高度的代理方法。通过block
将头视图、尾部视图实现引出到主视图加载,高度同样引出在主视图中返回。
3、主控制器创建tableview、source、delegate,tableview
引用source、delegate
对象。
以上步骤将source
、delegate
分离,可以复用到任意列表中,去除了重复部分,极大的减少了代码量,只需要在控制器中创建tableview
,处理数据并加载数据即可。
代码如下:
头文件:TableViewDataSource.h
//
// TableViewDataSource.h
// TableViewDataSource
//
// Created by hibo on 2019/6/10.
// Copyright © 2019 hibo. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedef void (^TableViewCellConfigureBlock)(id cell, id model, NSIndexPath * indexPath);
NS_ASSUME_NONNULL_BEGIN
@interface TableViewDataSource : NSObject<UITableViewDataSource>
@property (nonatomic,strong)NSArray *dataArr;//数据源
#pragma mark - source初始化将主要参数引出在主视图中处理数据展示
-(instancetype)initWithDataArr:(NSArray *)dataArr identifier:(NSString *)identifier configureCellBlock:(TableViewCellConfigureBlock)configureCellBlock;
@end
NS_ASSUME_NONNULL_END
//获取行高
typedef CGFloat (^TableViewRowHeightBlock)(NSIndexPath *indexPath);
//获取头视图高
typedef CGFloat (^TableViewHeaderHeightBlock)(NSInteger section);
//获取尾视图高
typedef CGFloat (^TableViewFooterHeightBlock)(NSInteger section);
//获取头视图view
typedef UIView *(^TableViewHeaderBlock)(NSInteger section);
//获取尾部试图view
typedef UIView *(^TableViewFooterBlock)(NSInteger section);
//delegate
@interface TableViewDelegate : NSObject<UITableViewDelegate>
//初始化行高、组高、头视图、尾部视图
-(instancetype)initWithRowHeight:(TableViewRowHeightBlock)rowHeightBlock
headerHeight:(TableViewHeaderHeightBlock)headerHeightBlock
footerHeight:(TableViewFooterHeightBlock)footerHeightBlock
header:(TableViewHeaderBlock)headerBlock
footer:(TableViewFooterBlock)footerBlock;
@end
实现文件:TableViewDataSource.m
//
// TableViewDataSource.h
// TableViewDataSource
//
// Created by hibo on 2019/6/10.
// Copyright © 2019 hibo. All rights reserved.
//
#import "TableViewDataSource.h"
@interface TableViewDataSource ()
@property(nonatomic, strong) NSArray* cells;
@property(nonatomic, copy) NSString* identifier;
@property(nonatomic, copy) TableViewCellConfigureBlock configureCellBlock;
@property(nonatomic, assign) BOOL isTwo;//是否为二维数组
@end
@implementation TableViewDataSource
#pragma mark - source初始化将主要参数引出在主视图中处理数据展示
-(instancetype)initWithDataArr:(NSArray *)dataArr identifier:(NSString *)identifier configureCellBlock:(TableViewCellConfigureBlock)configureCellBlock {
self = [super init];
if (self) {
self.dataArr = dataArr;
self.identifier = identifier;
self.configureCellBlock = configureCellBlock;
}
return self;
}
-(void)setDataArr:(NSArray *)dataArr{
_dataArr = dataArr;
self.isTwo = NO;
if (dataArr.firstObject) {
if ([dataArr.firstObject isKindOfClass:[NSArray class]]) {
self.isTwo = YES;
}
}
}
#pragma mark - 实现代理方法
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
if (self.dataArr.count==0) {
return 0;
}else{
return self.isTwo?self.dataArr.count:1;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.isTwo?[self.dataArr[section] count]:self.dataArr.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.identifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
id model = self.dataArr[indexPath.row];
self.configureCellBlock(cell, model, indexPath);
return cell;
}
@end
#pragma mark - 实现头视图、尾视图、头视图高度、尾视图高度的代理方法,将参数引出在主视图中获取
@interface TableViewDelegate ()
@property(nonatomic, copy) TableViewRowHeightBlock rowHeightBlock;
@property(nonatomic, copy) TableViewHeaderHeightBlock headerHeightBlock;
@property(nonatomic, copy) TableViewFooterHeightBlock footerHeightBlock;
@property(nonatomic, copy) TableViewHeaderBlock headerBlock;
@property(nonatomic, copy) TableViewFooterBlock footerBlock;
@end
@implementation TableViewDelegate
//初始化行高、组高、头视图、尾部视图
-(instancetype)initWithRowHeight:(TableViewRowHeightBlock)rowHeightBlock
headerHeight:(TableViewHeaderHeightBlock)headerHeightBlock
footerHeight:(TableViewFooterHeightBlock)footerHeightBlock
header:(TableViewHeaderBlock)headerBlock
footer:(TableViewFooterBlock)footerBlock{
self = [super init];
if (self) {
self.rowHeightBlock = rowHeightBlock;
self.headerHeightBlock = headerHeightBlock;
self.footerHeightBlock = footerHeightBlock;
self.headerBlock = headerBlock;
self.footerBlock = footerBlock;
}
return self;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (self.rowHeightBlock) {
return self.rowHeightBlock(indexPath);
}
return 0;
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
if (self.footerHeightBlock) {
return self.footerHeightBlock(section);
}
return 0;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
if (self.headerBlock) {
return self.headerBlock(section);
}
return nil;
}
-(UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section{
if (self.footerBlock) {
return self.footerBlock(section);
}
return nil;
}
@end
创建视图
#pragma mark - 创建列表
-(UITableView *)tableview{
if (_tableview==nil) {
_tableview = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) style:UITableViewStylePlain];
[_tableview registerClass:[MVCTableViewCell class] forCellReuseIdentifier:@"cell"];
_tableview.tableFooterView = [UIView new];
self.dataSource = [[TableViewDataSource alloc] initWithDataArr:self.present.dataArr identifier:@"cell" configureCellBlock:^(MVCTableViewCell *cell, Model *model, NSIndexPath *indexPath) {
cell.model = model;
}];
self.tableview.dataSource = self.dataSource;
self.delegate = [[TableViewDelegate alloc]initWithRowHeight:^CGFloat(NSIndexPath *indexPath) {
return 60;
} headerHeight:^CGFloat(NSInteger section) {
return 10;
} footerHeight:^CGFloat(NSInteger section) {
return 10;
} header:nil footer:nil];
self.tableview.delegate = self.delegate;
}
return _tableview;
}