美文网首页
iOS ViewController 瘦身实践

iOS ViewController 瘦身实践

作者: _浅墨_ | 来源:发表于2018-02-06 22:45 被阅读90次

    当我们每次重复性的在含有 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
    上海 虹桥

    相关文章

      网友评论

          本文标题:iOS ViewController 瘦身实践

          本文链接:https://www.haomeiwen.com/subject/dwlezxtx.html