控制器瘦身之UITableView抽取<一>

說抽取之前,我們還是先來看一段我們寫爛了的代碼:

抽取前前篇一律的代碼
//
//  ViewController.m
//  TableViewTest
//
//  Created by 遇見遠(yuǎn)洋 on 16/10/18.
//  Copyright ? 2016年 遇見遠(yuǎn)洋. All rights reserved.
//

#import "ViewController.h"
#import "YJYYCustomCell.h"

#define SCREENWIDTH [UIScreen mainScreen].bounds.size.width
#define SCREENHEIGHT [UIScreen mainScreen].bounds.size.height
#define RamdonColor [UIColor colorWithRed:arc4random()% 255/256.0 green:arc4random()% 255/256.0 blue:arc4random()% 255/256.0 alpha:1.0]

static NSString * const cellId = @"cellReuseIdentifier";

@interface ViewController ()<UITableViewDataSource,UITableViewDelegate>
@property (strong,nonatomic)UITableView *tableView;/**<tableView視圖*/
@property (strong,nonatomic)NSArray *dataArray;/**<數(shù)據(jù)源*/

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self.view addSubview:self.tableView];
}

#pragma mark - ******TableView相關(guān)的代理/數(shù)據(jù)源方法******
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
//    return self.dataArray.count;
    return 10;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    YJYYCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
    
    cell.backgroundColor = RamdonColor;
    return cell;
}

//tableView選中某一行
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    
}

//返回cell高度代理方法
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 80;
}

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
    return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
    [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

#pragma mark- XXXXXXXXXXXXXXX懶加載XXXXXXXXXXXXXXXXXXXX
/**
 *  tableView懶加載
 *
 *  @return tableView懶加載
 */
- (UITableView *)tableView {
    if (!_tableView) {
        _tableView =
        [[UITableView alloc] initWithFrame:CGRectMake(0, 64, SCREENWIDTH, SCREENHEIGHT) style:UITableViewStylePlain];
        _tableView.backgroundColor = [UIColor cyanColor];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        [_tableView registerClass:[YJYYCustomCell class] forCellReuseIdentifier:cellId];
    }
    return _tableView;
}

/**
 *  數(shù)據(jù)源懶加載
 *
 *  @return 數(shù)據(jù)源
 */
- (NSArray *)dataArray {
    if (!_dataArray) {
        _dataArray = [NSMutableArray array];
    }
    return _dataArray;
}

@end

看完這一段代碼,我是比較憂傷的,因?yàn)楹茉缫郧埃乙彩沁@么寫的,而且這樣的代碼寫了不知道多少次了,那么你是否有考慮過重復(fù)寫這樣的代碼非常的沒有意義呢?至少在我看來是沒有意義的,還是回到咱們的主題,講抽取之前,我覺得咱么先搞清楚上面這段代碼純在什么問題:

抽取前代碼存在的問題:
  1. 如果一個(gè)項(xiàng)目中有多個(gè)TableView,重復(fù)寫這樣的代碼很煩人,而且復(fù)用性很低
  2. 數(shù)據(jù)源方法和代理方法都寫在控制器中,如果一個(gè)控制器存在多個(gè)tableVIew不好管理,且容易造成控制器中代碼很臃腫
如何抽取

那么,看完了存在的問題,接下來就可以聊我們比較關(guān)注的東西了,那就是如何去抽取呢?
我們都知道,寫一個(gè)TableView最重要的東西那就是數(shù)據(jù)源和代理,也許你會(huì)很熟悉下面這兩句代碼:

self.tableView.delegate = self; 
self.tableView.dataSource = self;

聰明的你,肯定也能夠想到我想要說什么了吧,沒錯(cuò),就是從數(shù)據(jù)源和代理入手,既然你每次都要實(shí)現(xiàn)數(shù)據(jù)源和代理的方法,那么我就將它抽出去,今天,我們主要講的是抽取DataSource,代理的抽取比較麻煩今天暫時(shí)先不提及太多,有興趣可以繼續(xù)關(guān)注我的文章,以后有時(shí)間我再單獨(dú)抽時(shí)間來寫代理的抽取。

下面我們開始:

  1. 首先了解這句代碼的意思
self.tableView.dataSource = self

它的意思是 設(shè)置tableView的數(shù)據(jù)源為self,這個(gè)self就是必須要實(shí)現(xiàn)兩個(gè)數(shù)據(jù)源方法的對象,沒抽取之前我們一般都是指的控制器,既然知道了這一點(diǎn),那么抽取的重點(diǎn)就是,新建一個(gè)類 來 替換控制器成為數(shù)據(jù)源就可以了,當(dāng)然既然要充當(dāng)數(shù)據(jù)源的角色,那么就必須實(shí)現(xiàn)數(shù)據(jù)源協(xié)議,實(shí)現(xiàn)那兩個(gè)方法了,下面就看代碼吧:

//
//  YJYYDataSource.h
//  TableViewTest
//
//  Created by 遇見遠(yuǎn)洋 on 16/10/18.
//  Copyright ? 2016年 遇見遠(yuǎn)洋. All rights reserved.
//

#import <UIKit/UIKit.h>
typedef void (^ConfigCellBlock)(id cell, id model);

@interface YJYYDataSource : NSObject<UITableViewDataSource>

/**
 *  根據(jù)外界傳入的數(shù)據(jù)以及標(biāo)識(shí)返回一個(gè)數(shù)據(jù)源
 *
 *  @param dataArray  外界傳入的數(shù)據(jù)
 *  @param identifier 標(biāo)識(shí)符
 *  @param block      回調(diào)block用于配置cell數(shù)據(jù)
 *
 *  @return 數(shù)據(jù)源對象
 */
+ (instancetype)dataSourceWith:(NSArray *)dataArray identifier:(NSString *)identifier dataConfigBlock:(ConfigCellBlock)block;

@end
//
//  YJYYDataSource.m
//  TableViewTest
//
//  Created by 遇見遠(yuǎn)洋 on 16/10/18.
//  Copyright ? 2016年 遇見遠(yuǎn)洋. All rights reserved.
//

#import "YJYYDataSource.h"
#import "YJYYCustomCell.h"

#define RamdonColor [UIColor colorWithRed:arc4random()% 255/256.0 green:arc4random()% 255/256.0 blue:arc4random()% 255/256.0 alpha:1.0]

@interface YJYYDataSource ()
@property (strong,nonatomic)NSArray *dataArray;/**<數(shù)據(jù)入口*/

@property (nonatomic,copy) NSString * identifier/**<標(biāo)識(shí)符*/;

@property (nonatomic,copy) ConfigCellBlock configBlock/**<回調(diào)block*/;
@end

@implementation YJYYDataSource

+ (instancetype)dataSourceWith:(NSArray *)dataArray identifier:(NSString *)identifier dataConfigBlock:(ConfigCellBlock)block {
    YJYYDataSource * dataSource= [[YJYYDataSource alloc]init];
    dataSource.identifier = identifier;
    dataSource.dataArray = dataArray;
    dataSource.configBlock = block;
    return dataSource;
}

#pragma mark- XXXXXXXXXXXXXXX數(shù)據(jù)源方法XXXXXXXXXXXXXXXXXXXX
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.dataArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    YJYYCustomCell * cell = [tableView dequeueReusableCellWithIdentifier:self.identifier forIndexPath:indexPath];
    cell.backgroundColor = RamdonColor;
    id item = [self.dataArray objectAtIndex:indexPath.row];
    self.configBlock(cell,item);
    return cell;
}

@end

最后在控制器中這么寫:

//
//  ViewController.m
//  TableViewTest
//
//  Created by 遇見遠(yuǎn)洋 on 16/10/18.
//  Copyright ? 2016年 遇見遠(yuǎn)洋. All rights reserved.
//

#import "ViewController.h"
#import "YJYYCustomCell.h"
#import "YJYYDataSource.h"

#define SCREENWIDTH [UIScreen mainScreen].bounds.size.width
#define SCREENHEIGHT [UIScreen mainScreen].bounds.size.height

static NSString * const cellId = @"cellReuseIdentifier";

@interface ViewController ()<UITableViewDelegate>
@property (strong,nonatomic)UITableView *tableView;/**<tableView視圖*/
@property (strong,nonatomic)NSMutableArray *dataArray;/**<數(shù)據(jù)源*/
@property (nonatomic,strong) YJYYDataSource * dataSouce;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self.view addSubview:self.tableView];
}

#pragma mark- XXXXXXXXXXXXXXX懶加載XXXXXXXXXXXXXXXXXXXX
/**
 *  tableView懶加載
 *
 *  @return tableView懶加載
 */
- (UITableView *)tableView {
    if (!_tableView) {
        _tableView =
        [[UITableView alloc] initWithFrame:CGRectMake(0, 64, SCREENWIDTH, SCREENHEIGHT) style:UITableViewStylePlain];
        self.dataSouce = [YJYYDataSource dataSourceWith:self.dataArray identifier:cellId dataConfigBlock:^(id cell, id model) {
            [cell configCellWithModel:model];
        }];
        _tableView.delegate = self;
        _tableView.dataSource = self.dataSouce;
        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        [_tableView registerClass:[YJYYCustomCell class] forCellReuseIdentifier:cellId];
    }
    return _tableView;
}

/**
 *  數(shù)據(jù)源懶加載
 *
 *  @return 數(shù)據(jù)源
 */
- (NSMutableArray *)dataArray {
    if (!_dataArray) {
        _dataArray = [NSMutableArray array];
        for (int i = 0 ; i<10; i++) {
            [_dataArray addObject:@(i)];
        }
    }
    return _dataArray;
}

@end

其實(shí),說了那么多你只要記住一個(gè)思路就可以了:

將控制器承擔(dān)的數(shù)據(jù)源方法 轉(zhuǎn)移到別的類中

搞定,該收工了,不過我相信肯定會(huì)有很多小伙伴并沒有看懂,額,其實(shí)代碼來說并不難,如果看不懂的話,好好理解一下我上面的文字介紹吧,不理解的話可以留言也行 ,

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容