当我们每次重复性的在含有 tableView 的 ViewController 里面写 table view delegate 和 dataSource方法时,我们是否感到厌烦呢?出于尽量不做重复的事情的目的,我们是否可以把 tableView 代理方法抽取出一个公共类呢?答案当然是肯定的。
在沐风影音项目中,我将 table view dataSource 方法抽取出来,使用 ArrayDataSource 类进行统一管理。当一个 table view 中展示的是一个个对象,我们都可以使用这种方式。这样开始费一点时间,后来会节省很多时间,所谓磨刀不误砍柴工是也。
核心代码如下:
1. 公共类 ArrayDataSource
ArrayDataSource.h
#import <Foundation/Foundation.h>
typedef void (^TableViewCellConfigureBlock)(id cell, id item);
@interface ArrayDataSource : NSObject<UITableViewDataSource>
- (id)initWithItems:(NSArray *)anItems
cellIdentifier:(NSString *)aCellIdentifier
configureCellBlock:(TableViewCellConfigureBlock)aConfigureCellBlock;
- (id)itemAtIndexPath:(NSIndexPath *)indexPath;
@end
ArrayDataSource.m
#import "ArrayDataSource.h"
@interface ArrayDataSource ()
@property (nonatomic, strong) NSArray *items;
@property (nonatomic, copy) NSString *cellIdentifier;
@property (nonatomic, copy) TableViewCellConfigureBlock configureCellBlock;
@end
@implementation ArrayDataSource
- (id)init
{
return nil;
}
- (id)initWithItems:(NSArray *)anItems
cellIdentifier:(NSString *)aCellIdentifier
configureCellBlock:(TableViewCellConfigureBlock)aConfigureCellBlock
{
self = [super init];
if (self) {
self.items = anItems;
self.cellIdentifier = aCellIdentifier;
self.configureCellBlock = [aConfigureCellBlock copy];// 在初始化 cell 的时候赋值 configureCellBlock
}
return self;
}
- (id)itemAtIndexPath:(NSIndexPath *)indexPath
{
return self.items[(NSUInteger) indexPath.row];
}
#pragma mark UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier
forIndexPath:indexPath];
id item = [self itemAtIndexPath:indexPath];
self.configureCellBlock(cell, item);// 这里执行block方法,为cell元素赋值
return cell;
}
@end
沐风影音中使用的对象 MFFolder,当然你可以根据自己需要定义不同的模型,之后只要将 model 类传递给cell 就好了。
模型类 MFFolder.h
#import <Foundation/Foundation.h>
@interface MFFolder : NSObject
@property(nonatomic,strong) NSString *name;// 文件夹名称
@property(nonatomic,strong) NSString *imgName;// 缩略图名称
@property(nonatomic,strong) NSArray * subItems;// 子对象
@end
自定义cell MFFolderTableViewCell.h
#import <UIKit/UIKit.h>
@class MFFolder;
@interface MFFolderTableViewCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIImageView *imgVIew;
@property (weak, nonatomic) IBOutlet UILabel *nameLbl;
// 根据 MFFolder 配置 cell 内容
- (void)configureForFolder:(MFFolder *)folder;
@end
MFFolderTableViewCell.m
#import "MFFolderTableViewCell.h"
#import "MFFolder.h"
@implementation MFFolderTableViewCell
- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
/*
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
self = [super initWithStyle: style reuseIdentifier:reuseIdentifier];
if (self) {
NSArray *nibArray = [[NSBundle mainBundle]loadNibNamed:@"MFFolderTableViewCell" owner:nil options:nil];
self = [nibArray lastObject];
}
return self;
}*/
- (void)configureForFolder:(MFFolder *)folder
{
self.imgVIew.image = [UIImage imageNamed:folder.imgName];
self.nameLbl.text = folder.name;
self.nameLbl.numberOfLines = 0;
self.nameLbl.minimumScaleFactor = 0.6;
self.nameLbl.adjustsFontSizeToFitWidth = YES;
}
@end
3. viewController 移动文件页面,一个viewController示例
MFFolderViewController.m
#import "MFFolderViewController.h"
#import "ArrayDataSource.h"
#import "MFFolder.h"
#import "MFFolderTableViewCell.h"
#import "MFFileManager.h"
#import "MFFileTypeJudgmentUtil.h"
static NSString * const FolderCellIdentifier = @"FolderCell";
@interface MFFolderViewController ()
@property (weak, nonatomic) IBOutlet UITableView *myTableView;
@property (nonatomic, strong) ArrayDataSource * foldersArrayDataSource;
@property (nonatomic, strong) NSMutableArray *folders;// 当前页面含有的文件夹数组
@end
@implementation MFFolderViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"移动文件";
// 初始化数据源
[self loadDataArray];
// 设置tableView
[self setupTableView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
// 设置tableView
- (void)setupTableView
{
TableViewCellConfigureBlock configureCell = ^(MFFolderTableViewCell *cell, MFFolder *folder) {
[cell configureForFolder:folder];
};// 这里初始化 cellConfigureBlock
NSArray *items = [self.folders copy];
// 对比指针地址
NSLog(@"items== %p",items);
NSLog(@"self.folders== %p",self.folders);
self.foldersArrayDataSource = [[ArrayDataSource alloc] initWithItems:items
cellIdentifier:FolderCellIdentifier
configureCellBlock:configureCell];
self.myTableView.dataSource = self.foldersArrayDataSource;
// 如果使用 registerClass,需要在cell的实现文件中重写initWithStyle并加载自己的nib
// [self.myTableView registerClass:[MFFolderTableViewCell class] forCellReuseIdentifier:FolderCellIdentifier];
[self.myTableView registerNib:[UINib nibWithNibName:@"MFFolderTableViewCell" bundle:nil] forCellReuseIdentifier:FolderCellIdentifier];
}
#pragma mark UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
#pragma mark - Custom Methods
#pragma mark - 加载数据源
-(void)loadDataArray {
NSMutableArray * filesArr = [MFFileManager readDownloadedFiles:@""];
self.folders = [[NSMutableArray alloc] init];
for (NSString *name in filesArr) {
if ([MFFileTypeJudgmentUtil isFolderType:name]) {// 判断是否是文件夹
MFFolder *folder = [[MFFolder alloc] init];
folder.name = name;
folder.imgName = @"cellThumbnailFolder";
[self.folders addObject:folder];
}
}
}
@end
至此,一个简单的 tableView 瘦身示例完毕。
2018.02.05
上海 虹桥
网友评论