iOS基础-高级视图-UITableView--实例:QQ好友列表

事先已准备好plist文件,结构如下
1.Root为Array。
2.里面有十一个字典(每个字典为一个分组)
3.每个分组里有friends,name,online三个属性
4.friends属性里有若干字典(每个字典代表一个好友)
5.每个好友字典里有4个属性,name,icon,intro和vip
6.需要两个模型,分组模型和其里面的好友模型
一、加载模型数据
1.新建一个好友模型MJFriend,添加4个属性,提供加载模型数据的方法并实现
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *icon;
@property(nonatomic,copy)NSString *intro;
@property(nonatomic,assign,getter = isVip)B0OL vip;
+(instancetype)friendWithDict:(NSDictionary *)dict
{
return [self alloc] initWithDict:dict];
}

-(instancetype)initWithDict:(NSDictionary *)dict
{
if(self = [super init]){
//好友字典里所有的键值对都赋值给friend的4个属性了
[self setValueForKeysWithDictionary:dict]; //KVC
}
return self;
}
2.新建一个好友分组模型MJFriendGroup,添加3个属性,提供加载模型数据的方法并

实现
@property(nonatomic,copy)NSString *name;
@property(nonatomic,strong)NSArray *friends;//装的都是MJFriend模型
@property(nonatomic,assign)int online;

+(instancetype)groupWithDict:(NSDictionary *)dict
{
return [self alloc] initWithDict:dict];
}
-(instancetype)initWithDict:(NSDictionary *)dict
{
if (self == [super init]){
//1.注入所有属性(但是目前friends属性里装的是字典)
[self setValueForKeysWithDictionary:dict]; //KVC

//2.特殊处理friends属性(将friends字典转成MJFriend模型)
NSMutableArray *friendArray = [NSMutableArray array];
for (NSDictionary *dict in self.friends){
MJFriend *friend = [MJFriend friendWithDict:dict];
[friendArray addObject:friend];
}
self.friends = friendArray;
}
return self;
}
3.控制器拿到groups数组并懒加载(在其中将分组字典转为模型)
@property(nonatomic,strong)NSArray *groups; //安全起见用Array类型
-(NSArray *)groups
{
if(_groups == nil) {
NSArray *dictArray = [NSArray arrayWithContentsOfFile:[NSBundle

mainBundle] pathForResource:@"" ofType:nil];

NSMutableArray *groupArray = [NSMutableArray array];
for(NSDictionary *dict in dictArray){
MJFriendGroup *group = [MJFriendGroup groupWithDict:dict];
[groupArray addObject:group];
}
_groups = groupArray;
}
return _groups;
}
PS:groupArray数组里面装的就是group模型。group模型里面的friendsArray数组装

的是friend模型。

二、显示模型数据
0.将默认控制器MJViewController改为继承自UITableViewController。将storyboard

里的默认View删除,拖一个TableViewController,Class设置为MJViewController
如果不设置Class,那么就不会创建MJViewController,MJViewController里的代码

相当于白写。
1.设置数据源,遵守数据源协议,并实现数据源方法
#pragma mark - 数据源方法
第一个数据源方法:numberOfSectionsInTableView:方法
return self.groups.count;
第二个数据源方法:numberOfRowsInSection:方法
MJFriendGroup *group = self.groups[section];
return group.friends.count;
第三个数据源方法:numberOfRowsInSection:方法
{
//1.创建cell
MJFriendCell *cell = [MJFriend cellWithTableView:tableView];

//2.设置cell的数据
MJFriendGroup *group = self.groups[indexPath.section];
MJFriend *friend = group.friends[indexPath.row];
cell.friendData = friend;

return cell;
}

三、添加头部控件(头部控件也有循环利用机制)
1.设置代理,遵守代理协议,并实现代理方法
//内部会设置位置和尺寸,不用自己设置
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection

:(NSInteger)section
{
//1.创建头部控件
MJHeaderView *header = [MJHeaderView headerViewWithTableView:

tableView];
header.delegate = self;
//2.给header设置数据(给header传递模型)[重写完setGroup方法后进行]
header.group = self.groups[section];

return header;
}
2.1>自定义一个MJHeaderView,并提供一个类方法快速创建一个HeaderView
+(instancetype)headerViewWithTableView:(UITableView *)tableView
{
static NSString *ID = @"header";
MJHeaderView *header = [tableView

dequeueReusableHeaderFooterViewWithIdentifier:ID];
if (header == nil){
header = [MJHeaderView alloc] initWithRreuseIdentifier:ID];
}
return header;
}

2>重写initWithRreuseIdentifier:方法
//在这个初始化方法中,MJHeaderView的frame/bounds没有值
{
if(self = [super initWithRreuseIdentifier:reuseIdentifier]){
//添加子控件
//1.添加按钮
UIButton *nameView = [UIButton buttonWithType:UIButtonTypeCustom];
//设置按钮的背景图片
[nameView setBackgroundImage:[UIImage imageNamed:

@"buddy_header_bg"] forState:UIControlStateNormal];
[nameView setBackgroundImage:[UIImage imageNamed:

@"buddy_header_bg_highlighted"] forState:UIControlStateHighlighted];
//设置按钮内部左边的箭头图片
[nameView setImage:[UIImage imageNamed:@"buddy_header_arrow"]

forState:UIControlStateNormal];
[nameView setTitleColor[UIColor blackColor] forState:UIControlStateNormal];
//设置按钮的内容左对齐
nameView.contentHorizontalAlignment =

UIControlContentHorizontalAlignmentLeft;
//设置按钮的内边距
nameView.contentEdgeInsets = UIEdgeInsetsMake(0,10,0,0);
//设置标题的内边距
nameView.titleEdgeInsets = UIEdgeInsetsMake(0,10,0,0);
[nameView addTarget:self acton:@selector(nameViewClick)

forControlEvents:UIControlEventTouchUpInside];

//设置按钮内部的imageView的内容模式为居中(不要拉伸)
nameView.imageView.contentMode = UIViewContentModeCenter;
//超出边框的内容不需要裁剪
nameView.imageView.clipsToBounds = NO;
[self.contentView addSubview:nameView];
self.nameView = nameView; //声明成员属性后一定要赋值
//2.添加好友数
UILabel *countView = [[UILabel alloc] init];
countView.textAligment = NSTextAligmentRight;
countView.textColor = [UIColor grayColor];
[self.contentView addSubview:countView];
self.countView = countView; //声明成员属性后一定要赋值
}
return self;
}

经验:某个控件出不来
1.frame的尺寸和位置对不对(不要在初始化方法中设置frame)
2.hidden是否为YES
3.有没有添加到父控件中
4.alpha是否小于0.01
5.被其他控件挡住了
6.查看父控件的前面5个情况

PS:因为layoutSubviews方法里要用到nameView和countView,所以将它们声明成

成员属性
@property(nonatomic,weak) UILabel *countView;
@property(nonatomic,weak) UIButton *nameView;
//一般在这里面布局内部的子控件(设置子控件的frame)
//当一个控件的frame发生改变的时候就会调用
-(void)layoutSubviews
{
#warning 一定要调用父类的方法
[super layoutSubviews];

//1.设置按钮的frame
self.nameView.frame = self.bounds;

//2.设置好友数的frame
CGFloat countY = 0;
CGFloat countH = self.frame.size.height;
CGFloat countW = 150;
CGFloat countX = self.frame.size.width - 10 - countW;
self.countView.frame = CGRectMake(countX,countY,countW,countH);
}

//如果头部控件每一组高度一样,那么就用下面的方法设置高度
self.tableView.sectionHeaderHeight = 44;
//如果头部控件每一组高度不一样,那么就用下面的方法设置高度
//heightForHeaderInSection:

四、设置头部数据
1.在HeaderView中声明一个组模型属性
@property(nonatomic,strong)MJFriendGroup *group;
2.重写setter方法
-(void)setGroup:(MJFriendGroup *)group
{
_group = group;

// 1.设置按钮文字(组名)
[self.nameView setTitle:group.name forState:UIControlStateNormal];

//2.设置好友数(在线数/总数)
self.countView.text = [NSString stringWithFormat:@"%d/%

d",group.online,group.frinedns.count];
}
3.将创建cell和设置cell数据的代码封装起来
1>自定义一个Cell,继承自UITableViewCell
2>提供一个方法,传TableView返回一个cell,一个Cell对应一个Friend模型
+(instancetype)cellWithTableView:(UITableView *)tableView;
//friend是C++的关键字,不能用friend作为属性名
@property(nonatomic,strong)MJFriend *friendData;
3>重写setter方法(在这里给cell控件赋值)
-(void)setFriendData:(MJFriend *)friendData
{
_friendData = friendData;

self.imageView.image = [UIImage imageNamed:friendData];
self.textLabel.text = friendData.name;
self.textLabel.textColor = friendData.isVip ? [UIColor redColor] : [UIColor

blackColor];
self.detailTextLabel.text = friendData.intro;
}
4>实现cellWithTableView:方法
{
static NSString *ID = @"friend";
MJFirendCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil){
cell = [MJFirendCell alloc] initWithStyle:UITableViewCellStyleSubtitle

reuseIdentifier:ID];
}
return cell;
}

五、展开合并好友组
1.用addTarget:方法监听按钮点击
2.来到MJFriendGroup.h,声明一个BOOL属性(标识这组是否需要展开)
@property(nonatomic,assign,getter = isOpened) BOOL opened;
3.重写第二个数据源方法 numberOfRowsInSection:
MJFriendGroup *group = self.groups[section];
return (group.isOpened ? group.friends.count : 0);

4.实现按钮的方法
- (void)nameViewClick
{
//1.修改模型的标识(状态取反)
self.group.opened = !self.group.isOpened;
//2.刷新表格
if([self.delegate respondsToSelector:@selector

(headerViewDidClickNameView:)]) {
[self.delegate headerViewDidClickNameView:self];
}

5.来到MJHeaderView.h新建代理协议,添加代理属性(因为HeaderView想把它内部

的点击告诉控制器)
@protocol MJHeaderViewDelegate(NSObject)
@optional
-(void)headerViewDidClickNameView:(MJHeaderView *)headerView;
@property(nonatomic,weak)id<MJHeaderViewDelegate> delegate;

6.实现代理方法
#pragma mark - headerVIew的代理方法
//点击了headerView上的分组名按钮时就会调用
-(void)headerViewDidClickNameView:(MJHeaderView *)headerView
{
[self.tableView reloadData];
}
说明:因为只有控制器才有reloadData方法,所以headerVIew不能直接使用,只能委

托控制器这个"代理人"去刷新表格。

7.刷新表格是不会从缓存池里取的,会重新创建。所以拿到重新创建好的新View来修改
当一个控件被添加到父控件中就会调用(系统自动调用)
-(void)didMoveToSuperview
{
//控制箭头的状态
if [self.group.opened] {
self.nameView.imageView.transform = CGAffineTransformMakeRotation

(M_PI_2);
} else {
self.nameView.imageView.transform = CGAffineTransformMakeRotation(0);
}
}

时间: 2024-11-12 21:04:07

iOS基础-高级视图-UITableView--实例:QQ好友列表的相关文章

UI基础之UITableView案例QQ好友列表

一:模型数据 LLFriend #import <Foundation/Foundation.h> @interface LLFriend : NSObject /** * icon */ @property (nonatomic, copy) NSString *icon; /** * intro */ @property (nonatomic, copy) NSString *intro; /** * name */ @property (nonatomic, copy) NSString

iOS基础-高级视图-UITableView--实例:app管理

不利用xib而是利用storyboard里的默认动态cell来描述自定义cell一.在第三个数据源方法中加载cell{MJAppCell *cell = [tableView dequeueReusableCellWithIdentifier:@"app"];//将模型数据传给cell的时候会调用set方法,在set方法中覆盖按钮的数据和状态即可cell.app = self.apps[indexPath.row]; return cell;}PS:一个TableView可以备份多种类

Objective-c——UI基础开发第九天(QQ好友列表)

一.知识点: 1.双模型的嵌套使用 2.Button的对齐方式 3.优化UITableView的加载 4.layoutSubview的使用 5.cell的折叠代理 二.双模型的嵌套定义: 注意是将self.friends 尚未字典转模型进行的操作 二.cell的重用定义方式 方法一 QQCell *cell =[tableView dequeueReusableCellWithIdentifier:identifier]; /** 但是这种方法,如果不是在xib中定义了identifier是不会

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

需求:类似于QQ好友列表页面的显示,有好友分组,有好友数量,在线人数,vip会员.展开分组时显示分组好友,合并分组时不显示:具体效果图如下: 分析: 1.展开分组时显示分组好友,该功能可以使用显示UITableViewCell的数据即可: 2.分组头可以考虑使用一个headerView来实现: 示例文件结构: 具体实现步骤: 1.自定义数据模型类,由于plist文件中包含了2个字典,所以需要写2个数据模型: 2.自定义cell,属性包括数据模型以及生成可重用cell的方法,由于系统自带的子控件即

[iOS基础控件 - 6.9.3] QQ好友列表Demo TableView

A.需求 1.使用plist数据,展示类似QQ好友列表的分组.组内成员显示缩进功能 2.组名使用Header,展示箭头图标.组名.组内人数和上线人数 3.点击组名,伸展.缩回好友组 B.实现步骤 1.编写MVC结构 (1)根据plist文件结构,编写model,使用嵌套型 1 // 2 // FriendGroup.h 3 // FriendsList 4 // 5 // Created by hellovoidworld on 14/12/12. 6 // Copyright (c) 2014

【iOS基础控件 - 13】【Demo 】QQ好友列表TableView

A.需求 1.使用plist数据,展示类似QQ好友列表的分组.组内成员显示缩进功能 2.组名使用Header,展示箭头图标.组名.组内人数和上线人数 3.点击组名,伸展.缩回好友组 code source: B.实现步骤 1.编写MVC结构 (1)根据plist文件结构,编写model,使用嵌套型 1 // 2 // FriendGroup.h 3 // FriendsList 4 // 5 // Created by hellovoidworld on 14/12/12. 6 // Copyr

iOS TableView实现QQ好友列表(三)

上节我们讲到如何展示好友信息 iOS TableView实现QQ好友列表(二) http://blog.csdn.net/lwjok2007/article/details/46549111 接下来我们将分组点击的时候折叠起来. 首先新建一个可变字典用来存储当前列表是否展示 NSMutableArray *selectedArr;//控制列表是否被打开 selectedArr=[[NSMutableArray alloc]init]; 根据前两节所讲,我们讲分组名称放在section的heade

iOS-QQ好友列表 iOS 页面间几种传值方式(属性,代理,block,单例,通知)

主要是 点击按钮实现下拉 刷新数据 页面间传值 // // HMFriendsModel.h // QQ好友列表 // // Created by YaguangZhu on 15/9/1. // Copyright (c) 2015年 YaguangZhu. All rights reserved. // #import <Foundation/Foundation.h> @interface HMFriendsModel : NSObject @property(nonatomic,cop

tableView练习 -- QQ好友列表

LWTViewController.h // // LWTViewController.h // tableView练习 -- QQ好友列表 // // Created by apple on 14-6-1. // Copyright (c) 2014年 lwt. All rights reserved. // #import <UIKit/UIKit.h> @interface LWTViewController : UITableViewController @end LWTViewCon