UI基础--UITableView实现仿QQ好友列表页面

需求:类似于QQ好友列表页面的显示,有好友分组,有好友数量,在线人数,vip会员、展开分组时显示分组好友,合并分组时不显示:具体效果图如下:

分析:

1、展开分组时显示分组好友,该功能可以使用显示UITableViewCell的数据即可;

2、分组头可以考虑使用一个headerView来实现;

示例文件结构:

具体实现步骤:

1、自定义数据模型类,由于plist文件中包含了2个字典,所以需要写2个数据模型;

2、自定义cell,属性包括数据模型以及生成可重用cell的方法,由于系统自带的子控件即可满足实际要求,所以不用写frame模型了;

4、自定义HeaderView,包括模型数据属性和快速构造HeaderView的类方法,以及代理方法;

5、在控制器中写UITableView的 数据显示的方法;

具体代码:

Model:

 1 //
 2 //  JWFriend.h
 3 //  12-24-FriendGroup
 4 //
 5 //  Created by xiaomoge on 14/12/24.
 6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
 7 //
 8
 9 #import <Foundation/Foundation.h>
10
11 @interface JWFriend : NSObject
12 @property (nonatomic,copy) NSString *icon;
13 @property (nonatomic,copy) NSString *intro;
14 @property (nonatomic,copy) NSString *name;
15 @property (nonatomic,assign,getter=isVip) BOOL vip;
16 - (instancetype)initWithDic:(NSDictionary *)dic;
17 + (instancetype)friendWithDic:(NSDictionary *)dic;
18 @end
 1 //
 2 //  JWFriend.m
 3 //  12-24-FriendGroup
 4 //
 5 //  Created by xiaomoge on 14/12/24.
 6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
 7 //
 8
 9 #import "JWFriend.h"
10
11 @implementation JWFriend
12 - (instancetype)initWithDic:(NSDictionary *)dic {
13     if (self = [super init]) {
14         [self setValuesForKeysWithDictionary:dic];//KVC的使用
15     }
16     return self;
17 }
18 + (instancetype)friendWithDic:(NSDictionary *)dic {
19     return [[self alloc] initWithDic:dic];
20 }
21 @end
 1 //
 2 //  JWFriendGroup.h
 3 //  12-24-FriendGroup
 4 //
 5 //  Created by xiaomoge on 14/12/24.
 6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
 7 //
 8
 9 #import <Foundation/Foundation.h>
10
11 @interface JWFriendGroup : NSObject
12 @property (nonatomic,strong) NSArray *friends;
13 @property (nonatomic,copy) NSString *name;
14 @property (nonatomic,assign) int online;
15 /*
16  组头是否展开,默认为NO
17  */
18 @property (nonatomic,assign,getter=isExpend) BOOL expend;
19 - (instancetype)initWithDic:(NSDictionary *)dic;
20 + (instancetype)friendGroupWithDic:(NSDictionary *)dic;
21 + (NSMutableArray *)friendGroupList;
22 @end
 1 //
 2 //  JWFriendGroup.m
 3 //  12-24-FriendGroup
 4 //
 5 //  Created by xiaomoge on 14/12/24.
 6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
 7 //
 8
 9 #import "JWFriendGroup.h"
10 #import "JWFriend.h"
11 @implementation JWFriendGroup
12 - (instancetype)initWithDic:(NSDictionary *)dic {
13     if (self = [super init]) {
14         [self setValuesForKeysWithDictionary:dic];
15     }
16     return self;
17 }
18 + (instancetype)friendGroupWithDic:(NSDictionary *)dic {
19     return [[self alloc] initWithDic:dic];
20 }
21
22 + (NSMutableArray *)friendGroupList {
23     NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"friends" ofType:@"plist"]];
24
25     NSMutableArray *tempArray = [NSMutableArray array];
26
27     for (NSDictionary *dic in array) {//字典转模型
28         JWFriendGroup *friendGroup = [JWFriendGroup friendGroupWithDic:dic];
29
30         NSMutableArray *tem = [NSMutableArray array];
31         for (NSDictionary *dict in friendGroup.friends) {//模型里面还带有子弹,所以继续进行字典转模型步骤
32             JWFriend *friend = [JWFriend friendWithDic:dict];
33             [tem addObject:friend];
34         }
35         friendGroup.friends = tem;//转完模型后记得重新赋值
36         [tempArray addObject:friendGroup];
37     }
38     return tempArray;
39 }
40 @end

View:

 1 //
 2 //  JWFriendCell.h
 3 //  12-24-FriendGroup
 4 //
 5 //  Created by xiaomoge on 14/12/24.
 6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
 7 //
 8
 9 #import <UIKit/UIKit.h>
10 @class JWFriend;
11 @interface JWFriendCell : UITableViewCell
12 @property (nonatomic,strong) JWFriend *friendDatas;
13 + (instancetype)cellWithTableView:(UITableView *)tableView;
14 @end
 1 //
 2 //  JWFriendCell.m
 3 //  12-24-FriendGroup
 4 //
 5 //  Created by xiaomoge on 14/12/24.
 6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
 7 //
 8
 9 #import "JWFriendCell.h"
10 #import "JWFriend.h"
11 @implementation JWFriendCell
12 //快速构造一个可重用的cee
13 + (instancetype)cellWithTableView:(UITableView *)tableView {
14     static NSString *resue = @"cell";
15     JWFriendCell *cell = [tableView dequeueReusableCellWithIdentifier:resue];
16     if (!cell) {
17         cell = [[self alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:resue];
18     }
19     return cell;
20 }
21 //重写set方法,给各子控件赋值
22 - (void)setFriendDatas:(JWFriend *)friendDatas {
23     _friendDatas = friendDatas;
24     self.textLabel.text = friendDatas.name;
25     self.detailTextLabel.text = friendDatas.intro;
26     self.imageView.image = [UIImage imageNamed:friendDatas.icon];
27     self.textLabel.textColor = friendDatas.isVip ? [UIColor redColor] : [UIColor blackColor];//如果是vip,那么呢称字体为红色
28 }
29 @end
 1 //
 2 //  JWFriendHeaderView.h
 3 //  12-24-FriendGroup
 4 //
 5 //  Created by xiaomoge on 14/12/24.
 6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
 7 //
 8
 9 #import <UIKit/UIKit.h>
10 @class JWFriendGroup,JWFriendHeaderView;
11 @protocol JWFriendHeaderViewDelegate <NSObject>
12 @optional
13 - (void)clickNameBtn:(JWFriendHeaderView *)headerView;
14
15 @end
16 @interface JWFriendHeaderView : UITableViewHeaderFooterView
17 @property (nonatomic,strong) JWFriendGroup *friendGroup;
18 @property (nonatomic,assign) id<JWFriendHeaderViewDelegate> delegate;
19 + (instancetype)headerViewWithTableView:(UITableView *)tableView;
20 @end
 1 //
 2 //  JWFriendHeaderView.m
 3 //  12-24-FriendGroup
 4 //
 5 //  Created by xiaomoge on 14/12/24.
 6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
 7 //
 8
 9 #import "JWFriendHeaderView.h"
10 #import "JWFriendGroup.h"
11 @interface JWFriendHeaderView ()
12 @property (nonatomic,weak) UIButton *nameView;
13 @property (nonatomic,weak) UILabel *countLabel;
14 @end
15 @implementation JWFriendHeaderView
16 //快速构造一个可重用的组头
17 + (instancetype)headerViewWithTableView:(UITableView *)tableView {
18     static NSString *resue = @"head";//缓存池标识
19     JWFriendHeaderView *headerView = [tableView dequeueReusableCellWithIdentifier:resue];
20     if (!headerView) {
21         headerView = [[self alloc] initWithReuseIdentifier:resue];
22     }
23     return headerView;
24 }
25 //重写方法,初始化控件
26 - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier {
27     if (self = [super initWithReuseIdentifier:reuseIdentifier]) {
28         UIButton *nameBtn = [UIButton buttonWithType:UIButtonTypeCustom];
29         [self.contentView addSubview:nameBtn];
30         self.nameView = nameBtn;
31         //按钮的一些属性的设置
32         [nameBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
33         [nameBtn setImage:[UIImage imageNamed:@"buddy_header_arrow"] forState:UIControlStateNormal];
34         [nameBtn setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg"] forState:UIControlStateNormal];
35         [nameBtn setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg_highlighted"] forState:UIControlStateHighlighted];
36         nameBtn.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);//按钮内容的间距,左间距为10
37         nameBtn.titleEdgeInsets =  UIEdgeInsetsMake(0, 10, 0, 0);//文字内容的间距,左间距为10
38         nameBtn.imageView.contentMode = UIViewContentModeCenter;//不缩放按钮图片
39         nameBtn.imageView.clipsToBounds = NO;//图片超出部分不裁剪
40         nameBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;//设置左对齐
41         [nameBtn addTarget:self action:@selector(nameClick) forControlEvents:UIControlEventTouchUpInside];//注册按钮点击事件
42
43         UILabel *countLabel  = [[UILabel alloc] init];
44         [self.contentView addSubview:countLabel];
45         self.countLabel = countLabel;
46         //文本标签的一些属性的设置
47         countLabel.textAlignment = NSTextAlignmentRight;
48         countLabel.font = [UIFont systemFontOfSize:14];
49         countLabel.textColor = [UIColor grayColor];
50     }
51     return self;
52 }
53 //这个方法改变了组头的frame后就会调用,那么可以在这里设置frame了
54 - (void)layoutSubviews {
55     [super layoutSubviews];//记得必须先实现父类的该方法
56     self.nameView.frame = self.bounds;
57     CGFloat countX = self.bounds.size.width - 10 - 150;
58     self.countLabel.frame = CGRectMake(countX, 0, 150, 44);
59 }
60 //点击组头按钮事件
61 - (void)nameClick {
62     self.friendGroup.expend = !self.friendGroup.isExpend;//获取组头是否展开状态
63     [self expend];//调用封装的一个方法,如果展开,那么图片旋转90度,否则不展开
64     if ([self.delegate respondsToSelector:@selector(clickNameBtn:)]) {//通知代理,点击了组头按钮
65         [self.delegate clickNameBtn:self];
66     }
67 }
68 //重写set方法,给各控件赋值
69 - (void)setFriendGroup:(JWFriendGroup *)friendGroup {
70     _friendGroup = friendGroup;//这句记得写,否则会造成没有内容显示
71     [self.nameView setTitle:friendGroup.name forState:UIControlStateNormal];
72     self.countLabel.text = [NSString stringWithFormat:@"%d/%lu",friendGroup.online,(unsigned long)friendGroup.friends.count];
73     [self expend];//调用封装的一个方法,如果展开,那么图片旋转90度,否则不展开
74 }
75 //封装的方法,如果展开,那么图片旋转90度,否则旋转度为0
76 - (void)expend {
77     CGFloat angle = self.friendGroup.isExpend ? M_PI_2 : 0;
78     [UIView animateWithDuration:0.5 animations:^{
79         self.nameView.imageView.transform = CGAffineTransformMakeRotation(angle);
80     }];
81 }
82 @end

Controller:

 1 //
 2 //  ViewController.m
 3 //  12-24-FriendGroup
 4 //
 5 //  Created by xiaomoge on 14/12/24.
 6 //  Copyright (c) 2014年 xiaomoge. All rights reserved.
 7 //
 8
 9 #import "ViewController.h"
10 #import "JWFriend.h"
11 #import "JWFriendGroup.h"
12 #import "JWFriendHeaderView.h"
13 #import "JWFriendCell.h"
14 @interface ViewController () <JWFriendHeaderViewDelegate>
15 @property (nonatomic,strong) NSArray *friendGroup;
16 @end
17
18 @implementation ViewController
19 #pragma mark - 隐藏状态栏
20 - (BOOL)prefersStatusBarHidden {
21     return YES;
22 }
23 #pragma mark - 懒加载
24 - (NSArray *)friendGroup {
25     if (!_friendGroup) {
26         _friendGroup = [JWFriendGroup friendGroupList];
27     }
28     return _friendGroup;
29 }
30 - (void)viewDidLoad {
31     [super viewDidLoad];
32     //设置组头的高度
33     self.tableView.sectionHeaderHeight = 44;
34 }
35 #pragma mark - tableViewDatasouce的方法
36 //显示多少组数据
37 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
38     return self.friendGroup.count;
39 }
40 //每组数据显示多少行数据
41 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
42     return [self.friendGroup[section] isExpend ]?[self.friendGroup[section] friends].count : 0;//这里使用了三目运算符,主要是判断如果组头是展开的,那么显示行数据,否则显示为0
43 }
44 //显示每个cell的内容
45 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
46     JWFriendCell *cell = [JWFriendCell cellWithTableView:tableView];
47     cell.friendDatas = [self.friendGroup[indexPath.section] friends][indexPath.row];
48     return cell;
49 }
50 #pragma mark - JWFriendHeaderView的方法
51 //显示组头view的内容
52 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
53     JWFriendHeaderView *headerView = [JWFriendHeaderView headerViewWithTableView:tableView];
54     headerView.friendGroup = self.friendGroup[section];
55     headerView.delegate = self;
56     headerView.tag = section;//把section赋值给组头的tag
57     return headerView;
58 }
59 #pragma mark - JWFriendHeaderViewDelegate的方法
60 - (void)clickNameBtn:(JWFriendHeaderView *)headerView {
61     NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:headerView.tag];
62     [self.tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationNone];//判断点击的是哪个组头,然后加载对应的数据
63 }
64 @end
时间: 2024-08-02 02:50:59

UI基础--UITableView实现仿QQ好友列表页面的相关文章

UI基础--UITableView实现仿QQ聊天页面

需求:类似于QQ聊天页面的展示,内容包括有头像.时间.聊天内容.相同时间发生的内容,只显示第一条内容的时间,并且点击输入框时,可以滚动到最后一条内容信息.具体效果图: 实例的文件结构: 实现的具体步骤: 1.布局界面,主要包括一个UIImageView.3个UIButton.1个UITextField: 2.自定义数据模型类,并测试数据是否能正常加载: 3.自定义cell,由于每行数据的高度都是不规则的,所以考虑先自定义好frame再来写自定义cell.属性包括frame模型以及生成可重用cel

仿QQ好友列表界面的实现

TableView有2种style:UITableViewStylePlain 和 UITableViewStyleGrouped. 但是QQ好友列表的tableView给人的感觉似乎是2个style效果都有,但是tableView不能实现2种效果同时存在. 其实只是用到了Plain这个style,只是在cell的个数显示上做了个处理(个人见解,希望可以帮到有需要的人.....) 当通讯录那一组的cell的组头视图中的button是普通状态下的时候,并不是不显示cell,而是显示一个没有任何内容

仿qq好友列表

模仿qq好友列表布局,可收缩.展开 下载地址:http://www.devstore.cn/code/info/940.html 运行截图:   

ExpandableListView仿QQ好友列表

本例中,对ExpandableListView中的数据进行了封装,分为两个JavaBean,一个为Group类表示组信息,一个Child类表示该组下子列表信息: Group: public class Group { private String groupName;//分组名 private List<Child> childList;//该分组写子列表 public String getGroupName() { return groupName; } public void setGro

Android UI视图效果篇之仿QQ好友列表分组悬浮PinnedHeaderExpandableListView

楼主是在平板上測试的.图片略微有点大,大家看看效果就好 接下来贴源代码: PinnedHeaderExpandableListView.java 要注意的是 在 onGroupClick方法中parent.setSelectedGroup(groupPosition)这句代码的作用是点击分组置顶, 我这边不须要这个效果.QQ也没实用到,所以给凝视了.大家假设须要能够解开凝视 package com.xiaos.view; import android.content.Context; impor

Android UI设计: 仿QQ好友列表分组悬停,自定义Header,下拉刷新结合Demo

之前学习了Pulltorefresh,pinnedheaderexpanablelistview 但是结合起来还是有点麻烦的.尤其是像QQ这种.他不是单纯的第一个当做分组.他是分组上面还有几个按钮,还有搜索框,同时可以滑动,而且还可以悬停.想了试了好几种方法,都有BUG.最后用的一种方法. 1. pulltorefresh用的android.v4里面自带的,好像知乎也是 2. 悬停和分组用的网上的,然后我把第一个分组的样式改成了自定义的menu菜单,并且清空了child.这样看上去就像一个自定义

android列表收缩与展开仿QQ好友列表(非常详细,附源码)

好友QQ列表,可以展开,可以收起,在android中,以往用的比较多的是listview,虽然可以实现列表的展示,但在某些情况下,我们还是希望用到可以分组并实现收缩的列表,那就要用到android的ExpandableListView,今天研究了一下这个的用法,也参考了很多资料动手写了一个小demo,实现了基本的功能,下面直接上效果图以及源代码~! ExpandableListView是一个垂直滚动显示两级列表项的视图,与ListView不同的是,它可以有两层:每一层都能够被独立的展开并显示其子

UI基础--UITableView实现仿微博页面

需求:类似于微博内容页面的展示,内容包括有头像.呢称.会员标志.微博内容.微博图片(可有可没有).具体效果图: 实例的文件结构: 实现的具体步骤: 1.自定义数据模型类,并测试数据是否能正常加载: 2.设置storyBoard,把UIViewController改为UITableViewController,,并更改controller文件为继承自UITableViewController的自定义文件,设置关联; 3.自定义cell,由于每行数据的高度都是不规则的,所以考虑先自定义好frame再

iOS UITableView制作类似QQ好友列表视图

            1 #import <UIKit/UIKit.h> 2 3 @interface AppDelegate : UIResponder <UIApplicationDelegate> 4 5 @property (strong, nonatomic) UIWindow *window; 6 7 8 @end 1 #import "AppDelegate.h" 2 #import "RootViewController.h"