博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【利用TableView实现QQ好友列表】
阅读量:4291 次
发布时间:2019-05-27

本文共 5194 字,大约阅读时间需要 17 分钟。

上篇博客写了关于性能优化以及手工绘制自定义单元格内容,这篇我们利用TableView的Section的Header来实现类似QQ好友列表的效果。

TableView有一个代理方法

\
 

这个方法返回一个UIView对象,我们可以将一个Button对象设为这个Section的Header,在点击它的时候展开列表内容。

简单地看下假的好友列表数据

 

\
 

一个array中包含多个dictionary,字典中又包括组别的名字以及好友列表,好友也用一个字典来表示,分别有名称,是否在线以及头像图片名字。

加载数据

view sourceprint?
01.
- (void)loadData
02.
{
03.
NSString *path = [[NSBundle mainBundle] pathForResource:@"friends" ofType:@"plist"];
04.
_dataList = [NSArray arrayWithContentsOfFile:path];
05.
_headers = [NSMutableDictionary dictionaryWithCapacity:_dataList.count];
06.
 
07.
_groupNames = [NSMutableArray arrayWithCapacity:_dataList.count];
08.
for (NSInteger i = 0; i < _dataList.count; i++)
09.
{
10.
NSDictionary *dict = _dataList[i];
11.
[_groupNames addObject:dict[@"groupname"]];
12.
}
13.
}

之后我们开始写一个自定义的头部按钮来方便我们想要的布局

view sourceprint?
01.
- (id)initWithFrame:(CGRect)frame
02.
{
03.
self = [super initWithFrame:frame];
04.
if (self) {
05.
UIImage *image = [UIImage imageNamed:@"arrow-right"];
06.
[self setImage:image forState:UIControlStateNormal];
07.
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
08.
//[self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
09.
_open = NO;
10.
}
11.
return self;
12.
}
13.
 
14.
- (void)setOpen:(BOOL)open
15.
{
16.
_open = open;
17.
//设定点击旋转动画效果
18.
[UIView beginAnimations:nil context:nil];
19.
self.imageView.transform = CGAffineTransformMakeRotation(self.isOpen?M_PI_2:0);
20.
[UIView commitAnimations];
21.
}

有一个BOOL型的成员_open来记录button是否被点击的状态,在点击时,左侧的图片有一个短暂的旋转动画效果。

然后设置图片以及标题的位置

view sourceprint?
01.
//图像显示位置
02.
- (CGRect)imageRectForContentRect:(CGRect)contentRect
03.
{
04.
return CGRectMake(RMarginX, RMarginY, RIconSide, RIconSide);
05.
}
06.
 
07.
//标题显示位置
08.
- (CGRect)titleRectForContentRect:(CGRect)contentRect
09.
{
10.
return CGRectMake(RIconSide + 4*RMarginX, 0, contentRect.size.width, contentRect.size.height);
11.
}

在drawRect中还绘制了底部的分割线以及光泽,不过由于背景没有绘制渐变,光泽效果有些突兀。

绘制底边

view sourceprint?
01.
CGContextRef context = UIGraphicsGetCurrentContext();
02.
 
03.
CGContextSaveGState(context);
04.
CGContextSetStrokeColorWithColor(context, [UIColor darkGrayColor].CGColor);
05.
CGContextMoveToPoint(context, 0, rect.size.height);
06.
CGContextAddLineToPoint(context, 320, rect.size.height);
07.
CGContextSetLineWidth(context, 2.0f);
08.
CGContextStrokePath(context);
09.
CGContextRestoreGState(context);

然后是光泽效果

 

view sourceprint?
01.
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
02.
UIColor *light = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.1];
03.
UIColor *dark = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:0.35];
04.
NSArray *colors = @[(__bridge id)light.CGColor, (__bridge id)dark.CGColor];
05.
CGFloat locations[] = {
0.01.0};
06.
 
07.
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (__bridge CFArrayRef)colors, locations);
08.
 
09.
CGContextSaveGState(context);
10.
CGPoint start = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
11.
CGPoint end = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
12.
CGContextDrawLinearGradient(context, gradient, start, end, 0);
13.
 
14.
CGColorSpaceRelease(colorSpace);
15.
CGGradientRelease(gradient);
16.
CGContextRestoreGState(context);

接着我们还需要自定义一个单元格类来接受和绘制数据,

具体实现类似于上篇博客中介绍的手工绘制单元格的内容

这里只看数据绑定的部分

view sourceprint?
1.
- (void)bindFriend:(NSDictionary *)myFriend
2.
{
3.
_name = myFriend[@"name"];
4.
_online = [myFriend[@"isonline"] boolValue];
5.
_headerImage = [UIImage imageNamed:myFriend[@"imagename"]];
6.
 
7.
[self setNeedsDisplay];
8.
}

在完成头部绘制以及单元格绘制的准备后,我们就可以在控制器中实现代理方法,讲数据排版到界面上了。

显示头部视图

view sourceprint?
01.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
02.
{
03.
HeaderButton *header = _headers[@(section)];
04.
if (!header)
05.
{
06.
header = [HeaderButton buttonWithType:UIButtonTypeCustom];
07.
header.bounds = CGRectMake(0, 0, 320, RHeaderHeight);
08.
header.backgroundColor = [UIColor colorWithRed:0.4 green:0.4 blue:0.8 alpha:1.0];
09.
header.titleLabel.font = [UIFont systemFontOfSize:16.0f];
10.
NSString *title = _groupNames[section];
11.
[header setTitle:title forState:UIControlStateNormal];
12.
[header addTarget:self action:@selector(expandFriends:) forControlEvents:UIControlEventTouchUpInside];
13.
[_headers setObject:header forKey:@(section)];
14.
}
15.
return header;
16.
}

头部点击的监听方法
 

view sourceprint?
1.
- (void)expandFriends:(HeaderButton *)header
2.
{
3.
header.open = !header.isOpen;
4.
[self.tableView reloadData];
5.
}

点击的时候改变header的_open值,然后刷新视图内容。

根据header的_open来确定是否显示section中的列表

view sourceprint?
1.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
2.
{
3.
HeaderButton *header = _headers[@(section)];
4.
NSArray *array = [self arrayWithSection:section];
5.
NSInteger count = header.isOpen?array.count:0;
6.
return count;
7.
}

绑定数据并且显示单元格

view sourceprint?
01.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
02.
{
03.
HRFriendsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
04.
 
05.
NSArray *array = [self arrayWithSection:indexPath.section];
06.
[cell bindFriend:array[indexPath.row]];
07.
 
08.
return cell;
09.
}

这样我们的工作几乎就完成了,下面来看一下效果图

 

\

 

 

转载地址:http://cmqgi.baihongyu.com/

你可能感兴趣的文章
linux安全-禁止密码登录及root登录
查看>>
Java 中的类为什么要实现序列化呢 / JAVA中序列化和反序列化中的静态成员问题
查看>>
redis集群搭建及注意事项
查看>>
分布式演变过程中之Session集群解决方案
查看>>
拥有这些Java这些技术可以涨工资吗?
查看>>
MySql学习之Join查询
查看>>
简单介绍线程池在并发编程中的使用
查看>>
redis如何防止并发?
查看>>
无备份情况下恢复MySQL误删的表,这样做再也不用怕误删了
查看>>
MySQL断电恢复的一点简单分析
查看>>
linux进程网络流量监控工具nethogs
查看>>
String.ValueOf和toString区别
查看>>
分布式补偿事务处理方案 / 分布式计算是如何控制事务的?
查看>>
SQL之常用小技巧第一篇
查看>>
java互联网架构-Mybatis缓存机制
查看>>
spring 更换数据库
查看>>
Java回调机制是什么意思?
查看>>
程序员须知:面试中最容易被问到的18个算法题(附答案!)
查看>>
IT界最真实的面试实录(第一弹)
查看>>
阿里云服务器部署方案(nginx+tomcat+mysql)
查看>>