Description
GPJDataDrivenTableView
is a data-driven way to use UITableView.
GPJDataDrivenTableView has the following features:
- two-way data binding (mapping)
- bind UI element XXXCell on XXXData based on their class name
- send action from XXXCell to XXXData through
GPJTableViewData.didSelectAction
block
- the interface is intuitive, so it easy to use
- construct
dataArray
with various subclasses ofGPJTableViewData
- feed the
dataArray
to-[GPJDataDrivenTableView reloadDataArray:]
- construct
GPJDataDrivenTableView has the following advantages:
- decouple code by cell type, so we gain very fine granularity code decoupling
- XXXCell and XXXData resides in XXXData.h/.m
- YYYCell and YYYData resides in YYYData.h/.m
- there is NOT IndexPath in business code, so it eliminates errors around index
Then, we can add/delete/modify cell independently:
- addding a new kind of cell or a new cell instance will NOT affect others
- deleting a kind of cell or a cell instance will NOT affect others
- modifing a kind of cell or a cell instance will NOT affect others
Finally, our code can evolve with change of requirements harmoniously. 🎉🎉🎉Woohoo🎉🎉🎉
Usage
#import <GPJDataDrivenTableView/GPJDataDrivenTableView.h>
GPJDataDrivenTableView *dataDrivenTableView = [[GPJDataDrivenTableView alloc] initWithFrame:self.view.bounds];
dataDrivenTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
[self.view addSubview:dataDrivenTableView];
NSMutableArray *dataArray = [NSMutableArray array];
{
ActionData *actionData = [ActionData new];
actionData.didSelectAction = ^(id data) {
[weakSelf actionCellReloadAction:data];
};
[dataArray addObject:actionData];
}
{
ColorData *data = [ColorData new];
data.didSelectAction = ^(id data) {
[weakSelf colorCellAction:data];
};
[dataArray addObject:data];
}
[dataDrivenTableView reloadDataArray:dataArray];
Requirements
GPJDataDrivenTableView
works on iOS 6+ and requires ARC to build.
Installation
CocoaPods
pod 'GPJDataDrivenTableView'
Manual
- download the GPJDataDrivenTableView repository
- copy the GPJDataDrivenTableView sub-folder into your Xcode project
Example
Origin
The traditional way is index-driven, we implement the UITableViewDataSource’s or UITableViewDelegate’s methods base on indexPath:
-tableView:cellForRowAtIndexPath:
-tableView:heightForRowAtIndexPath:
-tableView:didSelectRowAtIndexPath:
This index-driven way based on indexPath results a lot of if-else
code segments, Various cells’ code mix together. it is error-prone, hard to evolve with change of requirements.
The new way is data-driven. GPJDataDrivenTableView set itself as UITableView’s dataSource and delegate, and mapping indexPath to data in its dataArray
properly and safely. we only need construct dataArray
and call reloadDataArray:
, that is it.
- construct
dataArray
with various subclasses ofGPJTableViewData
- feed the
dataArray
to-[GPJDataDrivenTableView reloadDataArray:]
Using data-driven way, we don’t need concern about indexPath. it is error-free, it is friendly to evolve with change of requirements.
Implementation Choices and Details
After comparing the composite, subclass, category implementation, I choose the subclass imeplementation.
There are three classes: GPJDataDrivenTableView, GPJTableViewCell, and GPJTableViewData
- GPJDataDrivenTableView: subclass of UITableView
- it implements UITableViewDataSource and UITableViewDelegate
- it has a
dataArray
property to hold instances ofGPJTableViewData
’s subclasses - it binds XXXCell on XXXData using name string substitution
- it responds
tableView:didSelectRowAtIndexPath:
and callGPJTableViewData.didSelectAction
block - it hides
dataSource
/delegate
to prevent error-usage - it exposes
gpjDataSource
/gpjDelegate
for extension and customization
- GPJTableViewCell: subclass of UITableViewCell, implement cell UI
- GPJTableViewData: subclass of NSObject, implement
-cellHeight
method to specify cell height.
The code base is only about two hundreds lines, go ahead to have a look. GPJDataDrivenTableView.m
Hope you enjoy it. github source code