一行代码,快速为UITableView创建Delegate和DataSource

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一行代码,快速为UITableView创建Delegate和DataSource相关的知识,希望对你有一定的参考价值。

只需一行代码,快速为UITableView创建Delegate和DataSource。


简介
CBTableViewDataSource是一个轻量级的用于快速创建UITableView的DataSource和Delegate的框架。它提供了一些方便的API,帮助用户以一种快速和有逻辑的方式创建DataSource和Delegate。

最偷懒的使用方式如下:
[_tableView cb_makeSectionWithData:self.viewModel.data andCellClass:[CustomCell class]];
[size=1.75em]

[Objective-C] 查看源文件 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// 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;
}
// ...


可以看到,步骤多而繁琐,维护十分困难。 而使用CBTableViewDataSource后

[Objective-C] 查看源文件 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
[_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   
}];


代码变得简练而富有层次感,更加符合人类的思维方式。
用法安装使用cocoapods下载

[Ruby] 查看源文件 复制代码
1
pod ‘CBTableViewDataSource‘

导入包

[Objective-C] 查看源文件 复制代码
1
#import <CBTableViewDataSource/CBTableViewDataSource.h>

创建DataSource和Delegate

[Objective-C] 查看源文件 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
[_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   
}];

例子仅使用Data

[Objective-C] 查看源文件 复制代码
1
_data = @[    @{[color=#183691]@"text"[/color]:[color=#183691]@"Following"[/color],[color=#183691]@"value"[/color]:[color=#183691]@"45"[/color]},    @{[color=#183691]@"text"[/color]:[color=#183691]@"Follower"[/color],[color=#183691]@"value"[/color]:[color=#183691]@"10"[/color]},    @{[color=#183691]@"text"[/color]:[color=#183691]@"Star"[/color],[color=#183691]@"value"[/color]:[color=#183691]@"234"[/color]},    @{[color=#183691]@"text"[/color]:[color=#183691]@"Setting"[/color],[color=#183691]@"accessoryType"[/color]:@(UITableViewCellAccessoryDisclosureIndicator)},    @{[color=#183691]@"text"[/color]:[color=#183691]@"Share"[/color],[color=#183691]@"accessoryType"[/color]:@(UITableViewCellAccessoryDisclosureIndicator)}];


则显示样式如下:

 

技术分享
具体详情请下载该项目,查看DemoTwoViewController.h和DemoTwoViewController.m.
使用自定义Cell

[Objective-C] 查看源文件 复制代码
1
[size=13.6px]- ([color=#a71d5d]void[/color])configure:([color=#086b3]NSDictionary[/color] *)row index:([color=#086b3]NSNumber[/color] * )index {    [color=#a71d5d]if[/color] (row[[color=#183691]@"avatar"[/color]]) {        [[color=#ed6a43]self[/color].avatarView [color=#086b3]setImage:[/color][UIImage [color=#086b3]imageNamed:[/color]row[[color=#183691]@"avatar"[/color]]]];    } [color=#a71d5d]else[/color] {        [[color=#ed6a43]self[/color].avatarView [color=#086b3]setImage:[/color][color=#086b3]nil[/color]];    }    [[color=#ed6a43]self[/color].nameLabel [color=#086b3]setText:[/color]row[[color=#183691]@"name"[/color]]];    [[color=#ed6a43]self[/color].titleLabel [color=#086b3]setText:[/color]row[[color=#183691]@"title"[/color]]];    [[color=#ed6a43]self[/color].detailLabel [color=#086b3]setText:[/color]row[[color=#183691]@"detail"[/color]]];    self.[color=#333333]circleView[/color].[color=#333333]hidden[/color] = row[[color=#183691]@"unread"[/color]] == [color=#086b3]nil[/color];    [color=#a71d5d]if[/color]([[color=#086b3]index[/color] [color=#086b3]intValue[/color]] &[color=#086b3]1[/color]) {        self.[color=#333333]contentView[/color].[color=#333333]backgroundColor[/color] = [UIColor [color=#086b3]colorWithRed:[/color][color=#086b3]0.95[/color] [color=#086b3]green:[/color][color=#086b3]0.96[/color] [color=#086b3]blue:[/color][color=#086b3]0.96[/color] [color=#086b3]alpha:[/color][color=#086b3]1.00[/color]];    } [color=#a71d5d]else[/color] {        self.[color=#333333]contentView[/color].[color=#333333]backgroundColor[/color] = [UIColor [color=#086b3]whiteColor[/color]];    }}




具体用法请查看项目中CustomCell.h和CustomCell.m文件 页面样式如下:

 

技术分享
详情请查看项目中DemoOneViewController.h和DemoOneViewController.m文件。
更灵活的设置

[Objective-C] 查看源文件 复制代码
1
2
3
4
5
[tableView [color=#086b3]cb_makeSection:[/color]^(CBTableViewSectionMaker * section) {    section.[color=#086b3]data[/color](@[]);    section.[color=#086b3]cell[/color]([CustomCell [color=#086b3]class[/color]]);    section.[color=#086b3]adapter[/color](^(CustomCell cell,[color=#a71d5d]id[/color] row,[color=#a71d5d]NSUInteger[/color] [color=#086b3]index[/color]) {        cell.[color=#086b3]configure[/color](row);    });    section.[color=#086b3]event[/color](^() {        [color=#969896]// do something[/color]    })    [color=#969896]// other setting[/color]}];[mw_shl_code]
这里展示的是单个section的情况。[b]CBTableViewSectionMaker对象支持设置以下属性:[/b]注意,这些设置都是针对单独的section设置的
[b]data[/b]设置UITableView所要展示的数据。参数是一个NSArray。 如下:
 
[mw_shl_code=objc,true]section.data(@[@(goods1),@(goods2),...]);


cell设置UITableView展示数据用的Cell Class。该Class会自动注册identifier,无需手动注册
如:

[Objective-C] 查看源文件 复制代码
1
section.cell([CustomCell [color=#086b3]class[/color]]);


adapter用于适配Cell和Data,如:

[Objective-C] 查看源文件 复制代码
1
section.adapter(^(CustomCell * cell,id row,NSUInteger index) {    [cell configure:row];    // ...});


event设置点击cell的响应事件。如:

[Objective-C] 查看源文件 复制代码
1
section.event(^([color=#a71d5d]NSUInteger[/color] index,[color=#a71d5d]id[/color] row) {    CustomViewController * controller = [CustomViewController [color=#086b3]new[/color]];    controller.[color=#333333]viewModel[/color].[color=#333333]data[/color] = row;    [[color=#ed6a43]self[/color].navigationController [color=#086b3]pushViewController:[/color]controller [color=#086b3]animated:[/color][color=#086b3]YES[/color]];});


height用于设置cell的高度。传一个固定的值。该高度只对该section有效。如:

[Objective-C] 查看源文件 复制代码
1
section.height([color=#086b3]100[/color]);


autoHeight设置自动动态计算cell高度。用于cell高度不一的场景。

[Objective-C] 查看源文件 复制代码
1
section.autoHeight();


该属性与height冲突,优先级是autoHeight > height。 也就是说当设置了autoHeight,则height失效,高度以autoHeight为准
headerTitle;设置section的headerTitle。用法如:

[Objective-C] 查看源文件 复制代码
1
2
3
4
5
section.headerTitle([color=#183691]"title"[/color]);[mw_shl_code]
[b]footerTitle;[/b]设置section的footerTitle。用法同上。
[b]headerView;[/b]设置section的Header View。用法如下:
 
[mw_shl_code=objc,true]section.headerView(^(){    UIView * headerView = [UIView [color=#086b3]alloc[/color]]initWithFrame:[color=#086b3]CGRectMake[/color]([color=#086b3]0[/color],[color=#086b3]0[/color],[color=#086b3]320[/color],[color=#086b3]40[/color]);    [color=#969896]// ...[/color]    [color=#a71d5d]return[/color] headerView;})


该属性与headerTitle冲突,当设置了headerView,以headerView为准。footerView;设置section的Footer View。用法同上 该属性与footerTitle冲突,当设置了footerView,以footerView为准。
多个section的情况

[Objective-C] 查看源文件 复制代码
1
[tableView [color=#086b3]cb_makeDataSource:[/color]^(CBTableViewDataSourceMaker * make) {    [make [color=#086b3]headerView:[/color]^{        [color=#a71d5d]return[/color] [HeaderView [color=#086b3]new[/color]];    }];    [make [color=#086b3]makeSection:[/color] ^(CBTableViewSectionMaker * section) {        section.[color=#086b3]data[/color](@[]);        section.[color=#086b3]cell[/color]();        section.[color=#086b3]adapter[/color]();        section.[color=#086b3]event[/color]();        [color=#969896]// ... so on[/color]    }];    [make [color=#086b3]makeSection:[/color] ^(CBTableViewSectionMaker * section) {        section.[color=#086b3]data[/color](@[]);        section.[color=#086b3]cell[/color]();        section.[color=#086b3]adapter[/color]();        section.[color=#086b3]event[/color]();        [color=#969896]// ... so on[/color]    }];    [make [color=#086b3]makeSection:[/color] ^(CBTableViewSectionMaker * section) {        section.[color=#086b3]data[/color](@[]);        section.[color=#086b3]cell[/color]();        section.[color=#086b3]adapter[/color]();        section.[color=#086b3]event[/color]();        [color=#969896]// ... so on[/color]    }];    [color=#969896]// .. so on[/color]    [make [color=#086b3]footView:[/color]^{        [color=#a71d5d]return[/color] [FooterView [color=#086b3]new[/color]];    }];}]


页面样式如下:

 

技术分享

 

技术分享具体的代码请查看项目中DemoThreeViewController.h和DemoThreeViewController.m文件。CBTableViewDataSourceMaker支持设置以下属性:注意这些属性都是针对整个UITableView
makeSection用于为UITableView添加一个section。用法如下:

[Objective-C] 查看源文件 复制代码
1
[tableView [color=#086b3]cb_makeDataSource:[/color]^(CBTableViewDataSourceMaker * make) {    [make [color=#086b3]makeSection:[/color] ^(CBTableViewSectionMaker * section) {       [color=#969896]// ...[/color]    }}]


height为整个UITableView的Cell设置默认高度。用法如下:

[Objective-C] 查看源文件 复制代码
1
make.height([color=#086b3]100[/color]);


该属性与CBTableViewSectionMaker设置的height和autoHeight冲突。优先级是autoHeight > height(section) > height(UITableView)
也就是说,当一个section设置了autoHeight,则以autoHeight为准,其他section未设置autoHeight,而设置了height(section),则以height(section)为准,如果两者都没有,则以height(UITableView)为准。height默认为40。
headerView设置UITableView的tableHeaderView,注意与section的headerView的区别,一个UITableView只有一个tableHeaderView。用法如下:

[Objective-C] 查看源文件 复制代码
1
make.headerView(^(){    UIView * headerView = [[UIView [color=#086b3]alloc[/color]]init];    [color=#969896]// ...[/color]    [color=#a71d5d]return[/color] headerView;});


footerView设置UITableView的tableFooterView,同上。
commitEditing设置UITableView的commitEditing代理方法,设置了该方法,则cell侧滑可以出现删除按钮。 可以在刚方法设置当cell处于编辑状态需要处理的事件。用法如下:

[Objective-C] 查看源文件 复制代码
1
[make [color=#086b3]commitEditing:[/color]^(UITableView * tableView, UITableViewCellEditingStyle * editingStyle, [color=#086b3]NSIndexPath[/color] * indexPath) {    [color=#969896]// do somethings.                [/color]}];


scrollViewDidScroll设置UITableView的scrollViewDidScroll代理方法,当UITableView滚动时会调用该方法。 可以使用该方法处理UITableView的滚动事件。

[Objective-C] 查看源文件 复制代码
1
[make [color=#086b3]scrollViewDidScroll:[/color]^(UIScrollView * scrollView) {    [color=#969896]// do somethings                [/color]}];

鸣谢感谢您的使用和支持。欢迎issue和pull request,我会在第一时间内处理。
在这个框架中,我参考了许多大神们设计的框架。比如API的设计就参考了著名的AutoLayout框架Masonry。而在动态计算cell的高度上,则参考了@forkingdog的UITableView-FDTemplateLayoutCell的做法。

感谢他们带给我的灵感。

 

 

代码下载:

http://www.code4app.com/thread-8859-1-1.html

以上是关于一行代码,快速为UITableView创建Delegate和DataSource的主要内容,如果未能解决你的问题,请参考以下文章

如何快速获取UITableView中每个动态创建的行的textvalue

在 Swift 中从 UITableView 中删除一行?

如何在 UITableView 按钮中快速获取特定的行按钮标题

UITableView 创建 4 个正方形

如何快速创建矩阵调查?

UITableView帧高度动画故障