一行代码,快速为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]
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后
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下载
1
|
pod
‘CBTableViewDataSource‘ |
导入包
1
|
#import
<CBTableViewDataSource/CBTableViewDataSource.h> |
创建DataSource和Delegate
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
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
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文件。
更灵活的设置
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,无需手动注册
如:
1
|
section.cell([CustomCell
[color=#086b3] class [/color]]); |
adapter用于适配Cell和Data,如:
1
|
section.adapter(^(CustomCell
* cell, id
row, NSUInteger
index) { [cell configure:row]; //
...}); |
event设置点击cell的响应事件。如:
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有效。如:
1
|
section.height([color=#086b3]100[/color]); |
autoHeight设置自动动态计算cell高度。用于cell高度不一的场景。
1
|
section.autoHeight(); |
该属性与height冲突,优先级是autoHeight > height。 也就是说当设置了autoHeight,则height失效,高度以autoHeight为准
headerTitle;设置section的headerTitle。用法如:
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的情况
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。用法如下:
1
|
[tableView
[color=#086b3]cb_makeDataSource:[/color]^(CBTableViewDataSourceMaker * make) { [make [color=#086b3]makeSection:[/color] ^(CBTableViewSectionMaker * section) { [color=#969896] //
...[/color] }}] |
height为整个UITableView的Cell设置默认高度。用法如下:
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。用法如下:
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处于编辑状态需要处理的事件。用法如下:
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的滚动事件。
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