概要
UITableViewのUITableViewDataSourceを分離し、
UIViewControllerを軽くする方法のObj-C版を共有します。
Swift版は、こちら♡
UITableViewを軽量化する!(Swift版)
やること
・UITableViewDataSourceをUIViewContorlllerから分離する
やらないこと
・UITableViewCellのレイアウトについて
・UITableViewDelegateの分離について
実装手順
今回は、テキストを表示するだけのシンプルなTableViewでご説明します。
- UITableViewDataSouceの拡張クラスを作る
- UITableViewCellの拡張したクラスを作る
- UIViewControllerから呼び出す
1. UITableViewDataSouceの拡張クラスを作る
ItemDataSource.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedef void (^TableViewCellConfigureBlock)(id cell, id item);
@interface ItemDataSource : NSObject<UITableViewDataSource>
-(id)initWithItems:(NSArray *)items
cellIdentifier:(NSString *)cellIdentifier
configureCellBlock:(TableViewCellConfigureBlock)configureCellBlock;
- (id)itemAtIndexPath:(NSIndexPath *)indexPath;
@end
ItemDataSource.m
#import "ItemDataSource.h"
@interface ItemDataSource ()
@property (nonatomic, strong) NSArray<NSString *> *items;
@property (nonatomic, copy) NSString *cellIdentifier;
@property (nonatomic, copy) TableViewCellConfigureBlock configureCellBlock;
@end
@implementation ItemDataSource
- (id)initWithItems:(NSArray *)items
cellIdentifier:(NSString *)cellIdentifier
configureCellBlock:(TableViewCellConfigureBlock)configureCellBlock
{
self = [super init];
if (self) {
self.items = items;っq
self.cellIdentifier = cellIdentifier;
self.configureCellBlock = [configureCellBlock copy];
}
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);
return cell;
}
@end
2. UITableViewCellの拡張したクラスを作る
ItemCell.h
#import <UIKit/UIKit.h>
UIKIT_EXTERN NSString * const CellIdentifier;
@interface ItemCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
- (void)configureForCell:(NSString *)title;
@end
ItemCell.m
#import "ItemCell.h"
@implementation ItemCell
NSString * const CellIdentifier = @"ItemCell";
- (void)configureForCell:(NSString *)title
{
self.titleLabel.text = title;
}
@end
3. UIViewControllerから呼び出す
今回作ったItemDataSourceのインスタンスをUITableViewのdataSourceプロパティにセットするだけです。
ViewController.m
#import "ViewController.h"
#import "ItemDataSource.h"
#import "ItemCell.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic, strong) ItemDataSource *dataSource;
@end
@implementation ViewController
#pragma mark - LifeCycle
- (void)viewDidLoad {
[super viewDidLoad];
[self setup];
}
#pragma mark - Private
- (void)setup {
self.dataSource = [[ItemDataSource alloc]
initWithItems:@[@"株式会社",@"スマート",@"デバイス",@"テクノロジー"]
cellIdentifier:CellIdentifier
configureCellBlock:^(ItemCell *cell, NSString *title) {
[cell configureForCell:title];
}];
self.tableView.dataSource = self.dataSource;
}
@end
完成イメージ
まとめ
Obj-CもSwift同様
UITableViewDataSourceを分離でき、UIViewControllerの肥大化を防げました。
誤りや、もっとよい方法がございましたら、ご指摘頂ければ幸いです。