您的位置:首页 > 其它

【利用TableView实现QQ好友列表】

2013-09-09 10:22 666 查看
上篇博客写了关于性能优化以及手工绘制自定义单元格内容,这篇我们利用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.0
,
1.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.
}


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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: