Latest 1.1.0
Homepage https://github.com/cocbin/CBTableViewDataSource
License MIT
Platforms ios 8.0
Authors

demo

Just one line to create DataSource and Delegate for UITableView.
中文文档 (Document in Chinese)

Introduction

CBTableViewDataSource is a lightweight Framework which was used to create DataSource and Delegate for UITableView quickly. It provides a simple API to create logical and easily maintained code.

The most lazy way to create DataSource like this:

[_tableView cb_makeSectionWithData:self.viewModel.data andCellClass:[CustomCell class]];

Of course, you must follow some convention in this way. At the same time, I also provides others flexible way to create DataSource.

Details as document below.

Why use

We always spend a lot of time and energy to create DataSource and Delegate for UITableView when we develop an App. While those code tend to repetitive and hard maintenance, because them located in each position of each delegate method. We must found them from corner to corner, and modified them when we maintain program.

However, CBTableViewDataSource changed all this, and provides a simple API to help us create logical and easily maintained code.

In order to make everyone notice advantages of this framework, let’s do a compare.

Native way below:


// Native vision

// define a enum to split section

typedef NS_ENUM(NSInteger, SectionNameDefine) {
    SECTION_ONE,
    SECTION_TWO,
    SECTION_THREE,
    SECTION_FOUR,
    //...
    COUNT_OF_STORE_SECTION
};

// define identifier for section

#define IDENTIFIER_ONE  @"IDENTIFIER_ONE"
#define IDENTIFIER_TWO  @"IDENTIFIER_TWO"
#define IDENTIFIER_THREE  @"IDENTIFIER_THREE"
#define IDENTIFIER_FOUR @"IDENTIFIER_FOUR"
//...

// register cell class for section

[self.tableView registerClass:[OneCell class] forCellWithReuseIdentifier:IDENTIFIER_ONE];
[self.tableView registerClass:[TwoCell class] forCellWithReuseIdentifier:IDENTIFIER_TWO];
[self.tableView registerClass:[ThreeCell class] forCellWithReuseIdentifier:IDENTIFIER_THREE];
[self.tableView registerClass:[FourCell class] forCellWithReuseIdentifier:IDENTIFIER_FOUR];

// implementation datasource protocol

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return COUNT_OF_STORE_SECTION;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return ((NSArray*)self.data[section]).count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSUInteger section = (NSUInteger) indexPath.section;
    NSUInteger index = (NSUInteger) indexPath.row;
    switch(section) {
        case SECTION_ONE:
        // to do something
            return cell;
        case SECTION_TWO:
        // to do something
            return cell;
        case SECTION_THREE:
        // to do something
            return cell;

            //...
    }

    return cell;
}
// ...

It is cumbersome and hard maintenance in this way.

While using CBTableViewDataSource:

[_tableView cb_makeDataSource:^(CBTableViewDataSourceMaker * make) {
    // section one
    [make makeSection:^(CBTableViewSectionMaker *section) {
        section.cell([OneCell class])
            .data(self.viewModel.oneDate)
            .adapter(^(OneCell * cell,id data,NSUInteger index){
                [cell configure:data];
            })
            .autoHeight();
    }];
    // section two
    [make makeSection:^(CBTableViewSectionMaker *section) {
        section.cell([TwoCell class])
            .data(self.viewModel.twoData)
            .adapter(^(FeedCell * cell,id data,NSUInteger index){
                [cell configure:data];
            })
            .autoHeight();
    }];

    // ... so on    
}];

It has been concise and layered. Most important is that it make codes accord with the man’s thought better.

Usage

Install

using cocoapods

pod 'CBTableViewDataSource'

Import

#import <CBTableViewDataSource/CBTableViewDataSource.h>

Create DataSource and Delegate

[_tableView cb_makeDataSource:^(CBTableViewDataSourceMaker * make) {
    // section one
    [make makeSection:^(CBTableViewSectionMaker *section) {
        section.cell([OneCell class])
            .data(self.viewModel.oneDate)
            .adapter(^(OneCell * cell,id data,NSUInteger index){
                [cell configure:data];
            })
            .autoHeight();
    }];
    // section two
    [make makeSection:^(CBTableViewSectionMaker *section) {
        section.cell([TwoCell class])
            .data(self.viewModel.twoData)
            .adapter(^(FeedCell * cell,id data,NSUInteger index){
                [cell configure:data];
            })
            .autoHeight();
    }];

    // ... so on    
}];

Example

Just using data

UITableView tableView = [UITableView new];
[tableView cb_makeSectionWithData:data];

It will use default UITalbeViewCell as Cell Class in this way.

The data must follow convention as follows:

  1. data is a NSArray (NSArray < NSDictionary >).
  2. The key of dictionary as follows:

    • text use to set text for UITableViewCell‘s textLabel
    • detail use to set text for UITableViewCell‘s detailTextLabel
    • value use to set text for UITableViewCell‘s detailTextLabel
    • image use to set image for UITableViewCell‘s imageView
    • accessoryType use to set accessory type for UITableViewCell

    value and detail both be used to set text for UITableViewCell‘s detailTextLabel. If use detail as key, the detailTextLabel will show at the bottom of textLabel. If use value as key, the detailTextLabel will show at the right of textLabel. Do not use both of them in the same time,and the first appear in array priority.

For example:

_data = @[
    @{@"text":@"Following",@"value":@"45"},
    @{@"text":@"Follower",@"value":@"10"},
    @{@"text":@"Star",@"value":@"234"},
    @{@"text":@"Setting",@"accessoryType":@(UITableViewCellAccessoryDisclosureIndicator)},
    @{@"text":@"Share",@"accessoryType":@(UITableViewCellAccessoryDisclosureIndicator)}];

UI as follows:

CBTableViewDataSource

Check detail on file named DemoTwoViewController.h and DemoTwoViewController.m.

Using custom cell

[tableView cb_makeSectionWithData:data andCellClass:[CustomCell class]];

CustomCell must provides a Configuer: method or Configuer:index: method to adapt data.

For example:

- (void)configure:(NSDictionary *)row index:(NSNumber * )index {
    if (row[@"avatar"]) {
        [self.avatarView setImage:[UIImage imageNamed:row[@"avatar"]]];
    } else {
        [self.avatarView setImage:nil];
    }
    [self.nameLabel setText:row[@"name"]];
    [self.titleLabel setText:row[@"title"]];
    [self.detailLabel setText:row[@"detail"]];
    self.circleView.hidden = row[@"unread"] == nil;

    if([index intValue] &1) {
        self.contentView.backgroundColor = [UIColor colorWithRed:0.95 green:0.96 blue:0.96 alpha:1.00];
    } else {
        self.contentView.backgroundColor = [UIColor whiteColor];
    }
}

Check detail on file named CustomCell.h and CustomCell.m

UI as follows:

CBTableViewDataSource

Check detail on file named DemoOneViewController.h and DemoOneViewController.m.

More flexible setting

[tableView cb_makeSection:^(CBTableViewSectionMaker * section) {
    section.data(@[]);
    section.cell([CustomCell class]);
    section.adapter(^(CustomCell cell,id row,NSUInteger index) {
        cell.configure(row);
    });
    section.event(^() {
        // do something
    })
    // other setting
}];

Here show the case of single section.

CBTableViewSectionMaker

CBTableViewSectionMaker was used to setting some attribute for section.
Available attribute as follows :

data

Setting the data be used show in UITableView,argument was required a NSArray.

For example:

section.data(@[@(goods1),@(goods2),...]);
cell

Setting the Cell Class which was used to show data.
The identifier of cell will be register automatically.

For example:

section.cell([CustomCell class]);
adapter

Was used to adapt cell and date.

For example:

section.adapter(^(CustomCell * cell,id row,NSUInteger index) {
    [cell configure:row];
    // ...
});
event

Was used to setting event when cell be touch, for example:

section.event(^(NSUInteger index,id row) {
    CustomViewController * controller = [CustomViewController new];
    controller.viewModel.data = row;
    [self.navigationController pushViewController:controller animated:YES];
});
height

Used to setting height for cell. Is required a static value.
This height just vail for current section.

section.height(100);
autoHeight

Used to setting dynamic calculate height for cell.

section.autoHeight();

If has setting autoHeight,the height will be invalid.

headerTitle;

Used to setting header title for section. For example:

section.headerTitle("title");
footerTitle;

Used to setting footer title for section. ditto.

headerView;

Used to setting header view for section. For example

section.headerView(^(){
    UIView * headerView = [UIView alloc]initWithFrame:CGRectMake(0,0,320,40);
    // ...
    return headerView;
})

If has setting headerView,headerTitle will be invalid.

footerView;

Used to setting footer view for section. ditto.

Multiple Section

[tableView cb_makeDataSource:^(CBTableViewDataSourceMaker * make) {
    [make headerView:^{
        return [HeaderView new];
    }];
    [make makeSection: ^(CBTableViewSectionMaker * section) {
        section.data(@[]);
        section.cell();
        section.adapter();
        section.event();
        // ... so on
    }];
    [make makeSection: ^(CBTableViewSectionMaker * section) {
        section.data(@[]);
        section.cell();
        section.adapter();
        section.event();
        // ... so on
    }];
    [make makeSection: ^(CBTableViewSectionMaker * section) {
        section.data(@[]);
        section.cell();
        section.adapter();
        section.event();
        // ... so on
    }];
    // .. so on
    [make footView:^{
        return [FooterView new];
    }];
}]

UI as follows:

CBTableViewDataSource
CBTableViewDataSource

Check detail on file named DemoThreeViewController.h and DemoThreeViewController.m.

CBTableViewDataSourceMaker

CBTableViewDataSourceMaker was used to setting some attribute for UITableView.
Available attribute as follows :

makeSection

Used to add a section for UITableView.For example:

[tableView cb_makeDataSource:^(CBTableViewDataSourceMaker * make) {
    [make makeSection: ^(CBTableViewSectionMaker * section) {
       // ...
    }
}]
height

Used to setting default height for UITableView

make.height(100);

If you had setting height or autoHeight for section, the height of here will invalid. Default is 40.

headerView

Used to setting tableHeaderView for UITableView.Notice the difference between tableHeaderView and section‘s headerView.

For example:

make.headerView(^(){
    UIView * headerView = [[UIView alloc]init];
    // ...
    return headerView;
});
footerView

Used to setting tableFooterView for UITableView. ditto.

commitEditing

Used to setting commitEditing method for UITableViewDelegate.

 [make commitEditing:^(UITableView * tableView, UITableViewCellEditingStyle * editingStyle, NSIndexPath * indexPath) {
    // do somethings.                
}];
scrollViewDidScroll

Used to setting scrollViewDidScroll method for UITableViewDelegate

[make scrollViewDidScroll:^(UIScrollView * scrollView) {
    // do somethings                
}];

Thinks

Thank you for using and supporting. Welcome to issue and pull request. I will deal with at first time.

I refer to many masters in this framework. For example, I refer to famous autolayout framework Masonary when I design API. The way to dynamic calculate cell height is refer to @forkingdog‘s UITableView-FDTemplateLayoutCell.

Thinks them for bring inspiration to me.

Contact me by email :[email protected]

Latest podspec

{
    "name": "CBTableViewDataSource",
    "version": "1.1.0",
    "summary": "An elegant style of writing for UITableViewDataSource",
    "description": "# CBTableViewDataSourcen![demo](media/demo.jpg)nnJust one line to create `DataSource` and `Delegate` for `UITableView`.n [u4e2du6587u6587u6863 (Document in Chinese)](https://github.com/cocbin/CBTableViewDataSource/blob/master/README_ZH.md)nn## Introductionnn`CBTableViewDataSource` is a lightweight Framework which was used to create `DataSource` and `Delegate` for `UITableView` quickly. It provides a simple API to create logical and easily maintained code.nnThe most lazy way to create `DataSource` like this:nn``` objective-cn[_tableView cb_makeSectionWithData:self.viewModel.data andCellClass:[CustomCell class]];n```nnOf course, you must follow some convention in this way. At the same time, I also provides others flexible way to create `DataSource`.nnDetails as document below.nn## Why usennWe always spend a lot of time and energy to create `DataSource` and `Delegate` for `UITableView` when we develop an App. While those code tend to repetitive and hard maintenance, because them located in each position of each delegate method.  We must found them from corner to corner, and modified them when we maintain program.nnHowever, `CBTableViewDataSource` changed all this, and provides a simple API to help us create logical and easily maintained code.nnIn order to make everyone notice advantages of this framework, let's do a compare.nnNative way below:nn``` objective-cnn// Native visionnn// define a enum to split sectionnntypedef NS_ENUM(NSInteger, SectionNameDefine) {n    SECTION_ONE,n    SECTION_TWO,n    SECTION_THREE,n    SECTION_FOUR,n    //...n    COUNT_OF_STORE_SECTIONn};nn// define identifier for sectionnn#define IDENTIFIER_ONE  @"IDENTIFIER_ONE"n#define IDENTIFIER_TWO  @"IDENTIFIER_TWO"n#define IDENTIFIER_THREE  @"IDENTIFIER_THREE"n#define IDENTIFIER_FOUR @"IDENTIFIER_FOUR"n//...nnn// register cell class for sectionnn[self.tableView registerClass:[OneCell class] forCellWithReuseIdentifier:IDENTIFIER_ONE];n[self.tableView registerClass:[TwoCell class] forCellWithReuseIdentifier:IDENTIFIER_TWO];n[self.tableView registerClass:[ThreeCell class] forCellWithReuseIdentifier:IDENTIFIER_THREE];n[self.tableView registerClass:[FourCell class] forCellWithReuseIdentifier:IDENTIFIER_FOUR];nnn// implementation datasource protocolnn- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {n    return COUNT_OF_STORE_SECTION;n}nn- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {n    return ((NSArray*)self.data[section]).count;n}nn- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {n    NSUInteger section = (NSUInteger) indexPath.section;n    NSUInteger index = (NSUInteger) indexPath.row;n    switch(section) {n        case SECTION_ONE:n        // to do somethingn            return cell;n        case SECTION_TWO:n        // to do somethingn            return cell;n        case SECTION_THREE:n        // to do somethingn            return cell;nn            //...n    }nn    return cell;n}n// ...nn```nnIt is cumbersome and hard maintenance in this way.nnWhile using `CBTableViewDataSource`:nn``` objective-cn[_tableView cb_makeDataSource:^(CBTableViewDataSourceMaker * make) {n    // section onen    [make makeSection:^(CBTableViewSectionMaker *section) {n        section.cell([OneCell class])n            .data(self.viewModel.oneDate)n            .adapter(^(OneCell * cell,id data,NSUInteger index){n                [cell configure:data];n            })n            .autoHeight();n    }];n    // section twon    [make makeSection:^(CBTableViewSectionMaker *section) {n        section.cell([TwoCell class])n            .data(self.viewModel.twoData)n            .adapter(^(FeedCell * cell,id data,NSUInteger index){n                [cell configure:data];n            })n            .autoHeight();n    }];nn    // ... so onn}];n```nnIt has been concise and layered. Most important is that it make codes accord with the man's thought better.nn## Usagen### Installnnusing `cocoapods`uff1ann``` rubynpod 'CBTableViewDataSource'n```nn### Importnn``` objective-cn#import n```nn### Create `DataSource` and `Delegate`nn``` objective-cn[_tableView cb_makeDataSource:^(CBTableViewDataSourceMaker * make) {n    // section onen    [make makeSection:^(CBTableViewSectionMaker *section) {n        section.cell([OneCell class])n            .data(self.viewModel.oneDate)n            .adapter(^(OneCell * cell,id data,NSUInteger index){n                [cell configure:data];n            })n            .autoHeight();n    }];n    // section twon    [make makeSection:^(CBTableViewSectionMaker *section) {n        section.cell([TwoCell class])n            .data(self.viewModel.twoData)n            .adapter(^(FeedCell * cell,id data,NSUInteger index){n                [cell configure:data];n            })n            .autoHeight();n    }];nn    // ... so onn}];n```nn## Examplenn### Just using datann``` objective-cnUITableView tableView = [UITableView new];n[tableView cb_makeSectionWithData:data];n```nnIt will use default `UITalbeViewCell` as Cell Class in this way.nnThe data must follow convention as followsuff1ann1. data is a NSArray (NSArray < NSDictionary * >*).n2. The key of dictionary as follows:n    - `text`                use to set text for `UITableViewCell`'s textLabeln    - `detail`              use to set text for `UITableViewCell`'s detailTextLabeln    - `value`               use to set text for `UITableViewCell`'s detailTextLabeln    - `image`               use to set image for `UITableViewCell`'s imageViewn    - `accessoryType`       use to set accessory type for `UITableViewCell`nn    `value` and `detail` both be used to set text for `UITableViewCell`'s detailTextLabel. If use `detail` as key, the `detailTextLabel` will show at the bottom of `textLabel`. If use `value` as key, the `detailTextLabel` will show at the right of `textLabel`. Do not use both of them in the same timeuff0cand the first appear in array priority.nnFor exampleuff1ann``` objective-cn_data = @[n    @{@"text":@"Following",@"value":@"45"},n    @{@"text":@"Follower",@"value":@"10"},n    @{@"text":@"Star",@"value":@"234"},n    @{@"text":@"Setting",@"accessoryType":@(UITableViewCellAccessoryDisclosureIndicator)},n    @{@"text":@"Share",@"accessoryType":@(UITableViewCellAccessoryDisclosureIndicator)}];n```nnUI as follows:nnCBTableViewDataSourcennCheck detail on file named `DemoTwoViewController.h` and `DemoTwoViewController.m`.nn### Using custom cellnn``` objective-cn[tableView cb_makeSectionWithData:data andCellClass:[CustomCell class]];n```nn`CustomCell` must provides a `Configuer:` method or `Configuer:index:` method to adapt data.nnFor example:nn``` objective-cn- (void)configure:(NSDictionary *)row index:(NSNumber * )index {n    if (row[@"avatar"]) {n        [self.avatarView setImage:[UIImage imageNamed:row[@"avatar"]]];n    } else {n        [self.avatarView setImage:nil];n    }n    [self.nameLabel setText:row[@"name"]];n    [self.titleLabel setText:row[@"title"]];n    [self.detailLabel setText:row[@"detail"]];n    self.circleView.hidden = row[@"unread"] == nil;nn    if([index intValue] &1) {n        self.contentView.backgroundColor = [UIColor colorWithRed:0.95 green:0.96 blue:0.96 alpha:1.00];n    } else {n        self.contentView.backgroundColor = [UIColor whiteColor];n    }n}n```nCheck detail on file named `CustomCell.h` and `CustomCell.m`nnUI as follows:nnCBTableViewDataSourcennCheck detail on file named `DemoOneViewController.h` and `DemoOneViewController.m`.nn### More flexible settingnn``` objective-cn[tableView cb_makeSection:^(CBTableViewSectionMaker * section) {ntsection.data(@[]);ntsection.cell([CustomCell class]);ntsection.adapter(^(CustomCell cell,id row,NSUInteger index) {nttcell.configure(row);nt});ntsection.event(^() {ntt// do somethingnt})nt// other settingn}];n```nnHere show the case of single section.nn#### CBTableViewSectionMakernn`CBTableViewSectionMaker` was used to setting some attribute for section.nAvailable attribute as follows :nn##### datannSetting the data be used show in `UITableView`,argument was required a NSArray.nnFor example:nn``` objective-cnsection.data(@[@(goods1),@(goods2),...]);n```nn##### cellnnSetting the `Cell Class` which was used to show data.nThe identifier of cell will be register automatically.nnFor example:nn``` objective-cnsection.cell([CustomCell class]);n```nn##### adapternnWas used to adapt cell and date.nnFor example:nn``` objection-cnsection.adapter(^(CustomCell * cell,id row,NSUInteger index) {n    [cell configure:row];n    // ...n});n```nn##### eventnnWas used to setting event when cell be touch, for example:nn``` objective-cnsection.event(^(NSUInteger index,id row) {n    CustomViewController * controller = [CustomViewController new];n    controller.viewModel.data = row;n    [self.navigationController pushViewController:controller animated:YES];n});n```nn##### heightnnUsed to setting height for `cell`. Is required a static value.nThis height just vail for current section.nn``` objective-cnsection.height(100);n```nn##### autoHeightnnUsed to setting dynamic calculate height for cell.nn``` objective-cnsection.autoHeight();n```nnIf has setting `autoHeight`,the `height` will be invalid.nn##### headerTitle;nnUsed to setting header title for section. For example:nn``` objective-cnsection.headerTitle("title");n```nn##### footerTitle;nnUsed to setting footer title for section. ditto.nn##### headerView;nnUsed to setting header view for section. For examplenn``` objective-cnsection.headerView(^(){n    UIView * headerView = [UIView alloc]initWithFrame:CGRectMake(0,0,320,40);n    // ...n    return headerView;n})n```nnIf has setting `headerView`,`headerTitle` will be invalid.nn##### footerView;nnUsed to setting footer view for section. ditto.nn###  Multiple Sectionnn``` objective-cn[tableView cb_makeDataSource:^(CBTableViewDataSourceMaker * make) {nt[make headerView:^{nttreturn [HeaderView new];nt}];nt[make makeSection: ^(CBTableViewSectionMaker * section) {nttsection.data(@[]);nttsection.cell();nttsection.adapter();nttsection.event();ntt// ... so onnt}];nt[make makeSection: ^(CBTableViewSectionMaker * section) {nttsection.data(@[]);nttsection.cell();nttsection.adapter();nttsection.event();ntt// ... so onnt}];nt[make makeSection: ^(CBTableViewSectionMaker * section) {nttsection.data(@[]);nttsection.cell();nttsection.adapter();nttsection.event();ntt// ... so onnt}];nt// .. so onnt[make footView:^{nttreturn [FooterView new];nt}];n}]n```nnUI as follows:nnnCBTableViewDataSourcennCBTableViewDataSourcennCheck detail on file named `DemoThreeViewController.h` and `DemoThreeViewController.m`.nn#### CBTableViewDataSourceMakern`CBTableViewDataSourceMaker` was used to setting some attribute for `UITableView`.nAvailable attribute as follows :nn##### makeSectionnUsed to add a section for `UITableView`.For example:nn``` objective-cn[tableView cb_makeDataSource:^(CBTableViewDataSourceMaker * make) {nt[make makeSection: ^(CBTableViewSectionMaker * section) {nt   // ...nt}n}]n```nn##### heightnUsed to setting default height for `UITableView`nn``` objective-cnmake.height(100);n```nnIf you had setting `height` or `autoHeight` for section, the `height` of here will invalid. Default is 40.nn##### headerViewnUsed to setting tableHeaderView for `UITableView`.Notice the difference between `tableHeaderView` and sectionu2018s `headerView`.nnFor example:nn``` objective-cnmake.headerView(^(){n    UIView * headerView = [[UIView alloc]init];n    // ...n    return headerView;n});n```nn##### footerViewnUsed to setting tableFooterView for `UITableView`. ditto.nn##### commitEditingnUsed to setting `commitEditing` method for `UITableViewDelegate`.nn``` objective-cn [make commitEditing:^(UITableView * tableView, UITableViewCellEditingStyle * editingStyle, NSIndexPath * indexPath) {n    // do somethings.n}];n```nn##### scrollViewDidScrollnUsed to setting `scrollViewDidScroll` method for `UITableViewDelegate`nn````objective-cn[make scrollViewDidScroll:^(UIScrollView * scrollView) {n    // do somethingsn}];n````nn## ThinksnnThank you for using and supporting. Welcome to issue and pull request. I will deal  with at first time.nnI refer to many masters in this framework. For example, I refer to famous `autolayout` framework `Masonary` when I design API. The way to dynamic calculate cell height is refer to `@forkingdog`'s `UITableView-FDTemplateLayoutCell`.nnThinks them for bring inspiration to me.nnContact me by email :[email protected]",
    "homepage": "https://github.com/cocbin/CBTableViewDataSource",
    "license": "MIT",
    "authors": {
        "Cocbin": "[email protected]"
    },
    "platforms": {
        "ios": "8.0"
    },
    "source": {
        "git": "https://github.com/cocbin/CBTableViewDataSource.git",
        "tag": "1.1.0"
    },
    "source_files": "CBTableViewDataSource/*.{h,m}"
}

Pin It on Pinterest

Share This