学习目标
1.【掌握】静态单元格应用
2.【掌握】动态原型应用
3.【理解】UITableViewHeaderFooterView
一、静态单元格应用
这个案例的目的是了解静态单元格的使用场合及操作方式,在一些情况下使用静态单元格会更加方便和快捷。我们需要了解静态单元格的一些特性及设置方式。案例效果图如下:
静态单元格只支持UITableViewController,所以先将之前的viewController删除。拖入UITableViewController,设置Size属性。再选择UITableView并设置属性Content属性为Static Cells:
Dynamin ProtoTypes:动态单元格,通过代码进行设置
Static Cells:静态单元格,通过界面进行设置,固定的。
设置每一组cell的数量:默认每一组有三个cell,修改每一组cell的数量。
设置cell的高度:Cell的高度也就是tableview的row height属性。
设置cell的显示样式:这里的样式和代码创建cell的系统提供的样式类似,不过多了一个Custom自定义。
设置cell的图片:给Cell设置图片,也就是Cell的image属性赋值。
设置cell的文本:
完成上面的操作后我们可以添加任意组(sections),设置对应组的行数(rows)。
需要注意的是,当我们删除原有控制器,创建新控制器后需要将新控制器设为初始显示的控制器。也就是勾选Is Initial View Controller,否则启动模拟器看不到界面。如下图所示:
二、动态原型应用
上面演示了静态单元格的使用,下面接着演示动态原型的使用,也就是UITableView的Content属性中的Dynamic protoTypes。设置这个属性后,我们可以通过代码根据原型动态创建Cell。下面来看看一个应用管理的案例,案例效果图如下:
首先,创建项目,导入素材图片和plist文件。
创建模型类,加载plist文件中的数据封装模型,并返回模型数组。
JFApp.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#import <Foundation/Foundation.h>
@interface JFApp : NSObject
@property(copy,nonatomic)NSString*size;
@property(copy,nonatomic)NSString*download;
@property(copy,nonatomic)NSString*name;
@property(copy,nonatomic)NSString*icon;
//快速创建模型
-(instancetype)initWithDictionary:(NSDictionary*)dict;
+(instancetype)appWithDictionary:(NSDictionary*)dict;
//返回模型数组
+(NSArray*)apps;
@end
|
JFApp.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#import "JFApp.h"
@implementationJFApp
//快速创建模型
-(instancetype)initWithDictionary:(NSDictionary*)dict{
if(self=[superinit]){
[self setValuesForKeysWithDictionary:dict];
}
returnself;
}
+(instancetype)appWithDictionary:(NSDictionary*)dict{
return[[selfalloc] initWithDictionary:dict];
}
//返回模型数组
+(NSArray*)apps{
NSArray*array=[NSArray arrayWithContentsOfFile:[[NSBundlemainBundle] pathForResource:@"apps_full.plist" ofType:nil]];
NSMutableArray*arrayM=[NSMutableArrayarray];
for(NSDictionary*dictinarray){
JFApp*app=[JFApp appWithDictionary:dict];
[arrayM addObject:app];
}
returnarrayM;
}
@end
|
在Main.storyboard中修改size为4.7,拖入一个全屏的UITableView控件,再拖入一个UITableViewCell 控件到UITableView中,并拖入Cell的子控件。Cell的高度也就是tableview的rowheight属性,tableview的 content属性默认就是Dynamic prototypes(动态原型),所以无需更改。
创建Cell封装类,并指定Cell的Class属性为我们创建的封装类JFAppCell。
指定Class后即可进行属性连线,一般属性连线我们都封装在类扩展(匿名分类,也叫延展)里,而不是.h文件中。
设置Cell的重用标识符(Identifier), 并在类中定义一个模型属性和快速创建Cell的方法并实现。点击下载按钮后,会弹出一个提示,弹出的提示不会跟随tableview滚动,所以需要添加这 个提示View到tableview的父视图中。这样就必须访问控制器,所以我们使用代理来完成这个操作,让控制器成为代理对象,替Cell完成点击事 件。
JFAppCell.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#import <UIKit/UIKit.h>
@classJFApp;
@classJFAppCell;
//定义一个代理
@protocolJFAppCellDelegate<NSObject>
@required
-(void)downloadButtonDidClick:(JFAppCell*)appCell;
@end
@interface JFAppCell : UITableViewCell
//为子控件赋值的模型属性
@property(strong,nonatomic)JFApp*app;
//代理属性
@property(weak,nonatomic)id<JFAppCellDelegate>delegate;
//快速创建cell的方法
+(instancetype)appCellWithDictionary:(UITableView*)tableView;
@end
|
JFAppCell.m
1
2
3
4
5
6
7
8
9
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
|
#import "JFAppCell.h"
#import "JFApp.h"
@interfaceJFAppCell()
@property(weak,nonatomic)IBOutletUIImageView*iconView;
@property(weak,nonatomic)IBOutletUILabel*nameView;
@property(weak,nonatomic)IBOutletUILabel*messageView;
@property(weak,nonatomic)IBOutletUIButton*downloadView;
//下载按钮的点击事件
-(IBAction)downloadButtonDidClick;
@end
@implementationJFAppCell
//下载按钮的点击事件
-(IBAction)downloadButtonDidClick{
//点击下载按钮后禁用下载按钮
self.downloadView.enabled=NO;
//弹出下载信息,弹出View是添加View到Tableview的父容器中,这里无法访问到。所以得用代理
if([self.delegate respondsToSelector:@selector(downloadButtonDidClick:)]){
[self.delegate downloadButtonDidClick:self];
}
}
//快速创建cell的方法
+(instancetype)appCellWithDictionary:(UITableView*)tableView{
//用cell重用标识符创建cell,这一步前必须在Cell中设置他的Identifier属性
JFAppCell*cell=[tableView dequeueReusableCellWithIdentifier:@"app"];
returncell;
}
//重写set方法为Cell的子控件赋值
-(void)setApp:(JFApp*)app{
_app=app;
//图标
self.iconView.image=[UIImage imageNamed:app.icon];
//名称
self.nameView.text=app.name;
//下载信息
self.messageView.text=[NSString stringWithFormat:@"大小:%@M | 下载量:%@万",app.size,app.download];
}
@end
|
在控制器对tableview进行控件连线,然后懒加载模型数组,并实现数据源方法和Cell的代理方法。最终实现我们的需求,具体控制器中的代码如下:
ViewController.m
1
2
3
4
5
6
7
8
9
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
#import "ViewController.h"
#import "JFApp.h"
#import "JFAppCell.h"
@interfaceViewController()<UITableViewDataSource,JFAppCellDelegate>
@property(weak,nonatomic)IBOutletUITableView*tableView;
@property(strong,nonatomic)NSArray*apps;
@end
@implementationViewController
//隐藏顶部状态栏
-(BOOL)prefersStatusBarHidden{
returnYES;
}
-(void)viewDidLoad{
[superviewDidLoad];
self.tableView.dataSource=self;
}
//懒加载
-(NSArray*)apps{
if(_apps==nil){
_apps=[JFAppapps];
}
return_apps;
}
//每组一共有多少行数据
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{
returnself.apps.count;
}
//创建cell
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
//获取当前数据模型
JFApp*app=self.apps[indexPath.row];
//创建cell
JFAppCell*cell=[JFAppCell appCellWithDictionary:tableView];
//指定Cell的代理对象
cell.delegate=self;
//为Cell赋值
cell.app=app;
returncell;
}
//实现Cell的代理方法,在下载按钮被点击后触发
-(void)downloadButtonDidClick:(JFAppCell*)appCell{
//创建提示Label
UILabel*downMessage=[[UILabelalloc] init];
//计算并设置frame
CGFloatdownW=200;
CGFloatdownH=20;
CGFloatdownX=(self.view.frame.size.width-downW)/2;
CGFloatdownY=(self.view.frame.size.height-downH)/2;
downMessage.frame=CGRectMake(downX,downY,downW,downH);
//设置一些属性
downMessage.text=[NSString stringWithFormat:@"%@正在下载...",appCell.app.name];
downMessage.backgroundColor=[UIColorgrayColor];
downMessage.textAlignment=NSTextAlignmentCenter;
downMessage.alpha=0;
//添加到self.view中
[self.view addSubview:downMessage];
//以动画形式弹出提示并隐藏,最终移除
[UIView animateWithDuration:1 animations:^{
downMessage.alpha=0.7;
} completion:^(BOOLfinished){
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(1*NSEC_PER_SEC)),dispatch_get_main_queue(),^{
[UIView animateWithDuration:1 animations:^{
downMessage.alpha=0;
} completion:^(BOOLfinished){
[downMessage removeFromSuperview];
}];
});
}];
}
@end
|
三、UITableViewHeaderFooterView
UITableViewHeaderFooterView是一个定义列表头部视图、列表尾部视图的类,HeaderFooterView一般是用在列表的头部,显示不同的分组状态信息。我们通过QQ分组来演示自定义HeaderFooterView的方法,下面是完成后的效果图:
导入素材和plist文件,从下图可以看出,我们需要创建嵌套模型,也就是每一个组好友和每一个好友都需要封装模型。
先封装单个好友模型,是否是vip定义为BOOL类型。
JFFriend.h
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#import <Foundation/Foundation.h>
@interface JFFriend : NSObject
@property(copy,nonatomic)NSString*icon;
@property(copy,nonatomic)NSString*intro;
@property(copy,nonatomic)NSString*name;
@property(assign,nonatomic,getter=isVip)BOOLvip;
//快速创建模型数组
-(instancetype)initWithDictionary:(NSDictionary*)dict;
+(instancetype)friendWithDictionary:(NSDictionary*)dict;
@end
|
JFFriend.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#import "JFFriend.h"
@implementationJFFriend
//快速创建模型数组
-(instancetype)initWithDictionary:(NSDictionary*)dict{
if(self=[superinit]){
[self setValuesForKeysWithDictionary:dict];
}
returnself;
}
+(instancetype)friendWithDictionary:(NSDictionary*)dict{
return[[selfalloc] initWithDictionary:dict];
}
@end
|
然后再封装一组好友的模型,因为好友分组是有收起、展开两种状态的,所以定义一个BOOL类型来存储好友组的状态。
JFFriendGroup.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#import <Foundation/Foundation.h>
@interface JFFriendGroup : NSObject
@property(strong,nonatomic)NSArray*friends;
@property(copy,nonatomic)NSString*name;
@property(assign,nonatomic)intonline;
//是否陈列出好友列表,默认不陈列
@property(assign,nonatomic,getter=isDisplay)BOOLdisplay;
//快速创建组模型
-(instancetype)initWithDictionary:(NSDictionary*)dict;
+(instancetype)friendGroupWithDictionary:(NSDictionary*)dict;
//返回组模型数组
+(NSArray*)friendGroups;
@end
|
JFFriendGroup.m
1
2
3
4
5
6
7
8
9
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
|
#import "JFFriendGroup.h"
#import "JFFriend.h"
@implementationJFFriendGroup
//快速创建组模型
-(instancetype)initWithDictionary:(NSDictionary*)dict{
if(self=[superinit]){
[self setValuesForKeysWithDictionary:dict];
//这样赋值后friends数组中是字典,需要转模型
NSMutableArray*arrayM_temp=[NSMutableArrayarray];
for(NSDictionary*dict_tempinself.friends){
JFFriend*myFriend=[JFFriend friendWithDictionary:dict_temp];
[arrayM_temp addObject:myFriend];
}
self.friends=arrayM_temp;
}
returnself;
}
+(instancetype)friendGroupWithDictionary:(NSDictionary*)dict{
return[[selfalloc] initWithDictionary:dict];
}
//返回组模型数组
+(NSArray*)friendGroups{
NSArray*array=[NSArray arrayWithContentsOfFile:[[NSBundlemainBundle] pathForResource:@"friends.plist" ofType:nil]];
NSMutableArray*arrayM=[NSMutableArrayarray];
for(NSDictionary*dictinarray){
JFFriendGroup*friendGroup=[JFFriendGroup friendGroupWithDictionary:dict];
[arrayM addObject:friendGroup];
}
returnarrayM;
}
@end
|
封装Cell类,这里的Cell是指好友而不是分组。也就是每一个Cell显示一个好友的信息,所以我们定义的模型属性是好友模型而不是好友分组模型。并且这里使用系统提供的Cell样式已经能够满足我们的需求,所以无需再手动创建。具体Cell类代码入下:
JFFriendCell.h
1
2
3
4
5
6
7
8
9
10
|
#import <UIKit/UIKit.h>
@classJFFriend;
@interface JFFriendCell : UITableViewCell
@property(strong,nonatomic)JFFriend*myFriend;
//快速创建cell
+(instancetype)friendCellWithTableView:(UITableView*)tableView;
@end
|
JFFriendCell.m
1
2
3
4
5
6
7
8
9
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
|
#import "JFFriendCell.h"
#import "JFFriend.h"
@implementationJFFriendCell
//快速创建cell
+(instancetype)friendCellWithTableView:(UITableView*)tableView{
staticNSString*ID=@"myFriend";
//从缓存中创建Cell
JFFriendCell*cell=[tableView dequeueReusableCellWithIdentifier:ID];
if(cell==nil){
//系统自带的样式已经能够满足我们的需求,所以无需手动创建,直接使用合适系统提供的cell样式
cell=[[JFFriendCellalloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
returncell;
}
//重写set方法为Cell赋值
-(void)setMyFriend:(JFFriend*)myFriend{
_myFriend=myFriend;
//为Cell赋值
self.imageView.image=[UIImage imageNamed:myFriend.icon];
self.textLabel.text=myFriend.name;
self.detailTextLabel.text=myFriend.intro;
//如果是vip则昵称是红色
if(myFriend.isVip){
self.textLabel.textColor=[UIColorredColor];
}
}
@end
|
封装好模型和Cell后我们就可以在控制器进行调用了,先显示出数据,再根据我们的需求进行修改。我们的QQ列表整个都是tableview,所以不用使用ViewController,直接使用TableviewController。在Main.storyboard中删除原有的ViewController拖入一个TableviewController。
然后再修改ViewController.h的继承父类为UITableViewController,才能设置新的控制器所属Class为这个类。
1
2
3
4
5
|
#import <UIKit/UIKit.h>
//修改继承的父类为UITableViewController
@interfaceViewController: UITableViewController
@end
|
设置UITableViewController的Class属性为ViewController,我们也可以新创建一个类继承自UITableViewController,然后在这里设置Class为我们新创建的那个类。
在控制器中懒加载数据,实现数据源方法显示出数据。因为我们Main.storyboard中使用的是TableViewController,所以无需手动遵守数据源、代理协议和手动指定数据源对象、代理对象。
ViewController.m
1
2
3
4
5
6
7
8
9
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
61
62
63
64
|
#import "ViewController.h"
#import "JFFriendGroup.h"
#import "JFFriendCell.h"
#import "JFFriend.h"
@interfaceViewController()
@property(strong,nonatomic)NSArray*friendGroups;
@end
@implementationViewController
//隐藏状态栏
-(BOOL)prefersStatusBarHidden{
returnYES;
}
-(void)viewDidLoad{
[superviewDidLoad];
}
//懒加载
-(NSArray*)friendGroups{
if(_friendGroups==nil){
_friendGroups=[JFFriendGroupfriendGroups];
}
return_friendGroups;
}
//一共多少组,每一个小组就是一组
-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView{
returnself.friendGroups.count;
}
//每组多少行
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{
//获取组模型
JFFriendGroup*friendGroup=self.friendGroups[section];
returnfriendGroup.friends.count;
}
//创建Cell
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
//获取组模型
JFFriendGroup*friendGroup=self.friendGroups[indexPath.section];
//获取单个好友模型
JFFriend*myFriend=friendGroup.friends[indexPath.row];
//创建cell
JFFriendCell*cell=[JFFriendCell friendCellWithTableView:tableView];
//为Cell赋值
cell.myFriend=myFriend;
returncell;
}
@end
|
完成后的效果为:
数据已经显示出来了,但是没有进行分组。如果我们使用系统自带的分组样式,是无法满足需求的。比如整个分组头部可以点击,并且带小图标,说明这整个分组头部是一个按钮,并且按钮上还有一个Label用来显示在线人数。
下面开始自定义ViewHeaderFooterView,创建一个类并继承自UITableViewHeaderFooterView类。headerView点击后会展开列表,也就是会刷新tableview,这个操作在headerView中是无法完成的(不能将控制器做参数传递)。所以我们通过代理来完成,让控制器成为headerView的代理对象,并实现对应的代理方法来完成这个需求。
JFHeaderView.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#import <UIKit/UIKit.h>
@classJFFriendGroup;
@classJFHeaderView;
@protocolJFHeaderViewDelegate<NSObject>
-(void)headerViewButtonDidClick:(JFHeaderView*)headerView;
@end
@interface JFHeaderView : UITableViewHeaderFooterView
//返回一个headerView
+(instancetype)headerViewWithTableView:(UITableView*)tableView;
@property(strong,nonatomic)JFFriendGroup*friendGroup;
//headerView的代理属性
@property(weak,nonatomic)id<JFHeaderViewDelegate>delegate;
@end
|
JFHeaderView.m
1
2
3
4
5
6
7
8
9
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#import "JFHeaderView.h"
#import "JFFriendGroup.h"
@interfaceJFHeaderView()
@property(weak,nonatomic)UIButton*btn;//headerView按钮
@property(weak,nonatomic)UILabel*lbl;//在线人数
@end
@implementationJFHeaderView
//返回一个headerView
+(instancetype)headerViewWithTableView:(UITableView*)tableView{
staticNSString*headerID=@"header";
JFHeaderView*headerView=[tableView dequeueReusableHeaderFooterViewWithIdentifier:headerID];
if(headerView==nil){
headerView=[[JFHeaderViewalloc] initWithReuseIdentifier:headerID];
}
returnheaderView;
}
//重写initWithReuseIdentifier:方法创建自定义headerView
-(instancetype)initWithReuseIdentifier:(NSString*)reuseIdentifier{
if(self=[super initWithReuseIdentifier:reuseIdentifier]){
UIButton*btn=[[UIButtonalloc] init];
[btn setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg_highlighted"] forState:UIControlStateHighlighted];
[btn setImage:[UIImage imageNamed:@"buddy_header_arrow"] forState:UIControlStateNormal];
btn.contentHorizontalAlignment=UIControlContentHorizontalAlignmentLeft;
btn.contentEdgeInsets=UIEdgeInsetsMake(0,10,0,0);
btn.titleEdgeInsets=UIEdgeInsetsMake(0,10,0,0);
[btn setTitleColor:[UIColorblackColor] forState:UIControlStateNormal];
btn.imageView.contentMode=UIViewContentModeCenter;
btn.imageView.clipsToBounds=NO;
//添加到headerView
[self addSubview:btn];
self.btn=btn;
[self.btn addTarget:self action:@selector(headerViewButtonDidClick) forControlEvents:UIControlEventTouchUpInside];
UILabel*lbl=[[UILabelalloc] init];
//文本右对齐
lbl.textAlignment=NSTextAlignmentRight;
[self addSubview:lbl];
self.lbl=lbl;
}
returnself;
}
//按钮单击事件
-(void)headerViewButtonDidClick{
self.friendGroup.display=!self.friendGroup.isDisplay;
if([self.delegate respondsToSelector:@selector(headerViewButtonDidClick:)]){
[self.delegate headerViewButtonDidClick:self];
}
}
//当一个新的headerView已经添加到某个父控件中的时候调用这个方法
-(void)didMoveToSuperview{
if(self.friendGroup.isDisplay){
self.btn.imageView.transform=CGAffineTransformMakeRotation(M_PI_2);
}else{
self.btn.imageView.transform=CGAffineTransformMakeRotation(0);
}
}
//重写set方法为headerView赋值
-(void)setFriendGroup:(JFFriendGroup*)friendGroup{
_friendGroup=friendGroup;
//设置组名
[self.btn setTitle:friendGroup.name forState:UIControlStateNormal];
//设置在线人数
self.lbl.text=[NSString stringWithFormat:@"%d / %lu",friendGroup.online,friendGroup.friends.count];
}
//当将这个控件真正添加到父控件的时候,会调用这个方法设置当前控件的所有子控件的frame
-(void)layoutSubviews{
[superlayoutSubviews];
self.btn.frame=CGRectMake(0,0,self.frame.size.width,self.frame.size.height);
self.lbl.frame=CGRectMake(300,0,60,44);
}
@end
|
在控制器中遵守JFHeaderViewDelegate代理协议并实现代理方法,实现单组数据刷新。
ViewController.m
1
2
3
4
5
6
7
8
9
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
#import "ViewController.h"
#import "JFFriendGroup.h"
#import "JFFriendCell.h"
#import "JFFriend.h"
#import "JFHeaderView.h"
@interfaceViewController()<JFHeaderViewDelegate>
@property(strong,nonatomic)NSArray*friendGroups;
@end
@implementationViewController
//隐藏状态栏
-(BOOL)prefersStatusBarHidden{
returnYES;
}
-(void)viewDidLoad{
[superviewDidLoad];
//设置headerView的高度
self.tableView.sectionHeaderHeight=50;
}
//懒加载
-(NSArray*)friendGroups{
if(_friendGroups==nil){
_friendGroups=[JFFriendGroupfriendGroups];
}
return_friendGroups;
}
//一共多少组,每一个小组就是一组
-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView{
returnself.friendGroups.count;
}
//每组多少行
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{
//获取组模型
JFFriendGroup*friendGroup=self.friendGroups[section];
//是否展开好友
if(friendGroup.isDisplay){
returnfriendGroup.friends.count;
}else{
return0;
}
}
//创建Cell
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
//获取组模型
JFFriendGroup*friendGroup=self.friendGroups[indexPath.section];
//获取单个好友模型
JFFriend*myFriend=friendGroup.friends[indexPath.row];
//创建cell
JFFriendCell*cell=[JFFriendCell friendCellWithTableView:tableView];
//为Cell赋值
cell.myFriend=myFriend;
returncell;
}
//创建headerView
-(UIView*)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section{
JFFriendGroup*friendGroup=self.friendGroups[section];
JFHeaderView*headerView=[JFHeaderView headerViewWithTableView:tableView];
//存储组
headerView.tag=section;
//指定控制器为代理
headerView.delegate=self;
headerView.friendGroup=friendGroup;
returnheaderView;
}
//点击headerView按钮的时候触发
-(void)headerViewButtonDidClick:(JFHeaderView*)headerView{
NSIndexSet*indexSet=[NSIndexSet indexSetWithIndex:headerView.tag];
//刷新指定组
[self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationFade];
}
|
关于重用:
UITableViewHeaderFooterView与UITableViewCell在滑动屏幕时都可以根据标志进行重用,而在不滑动而只进行reloadData等刷新数据操作时,两者有不同表现:UITableViewHeaderFooterView将不能根据标志重用(即系统不会将其放入缓冲区),会创建新的视图代替旧的。UITableViewCell能根据标志重用。所以在自定义UITableViewHeaderFooterView首尾视图时,要注意刷新数据时对视图的处理。