//
// ViewController.m
// 02QQ好友列表
//
// Created by Itcast.GuangZhou on 15/9/25.
// Copyright (c) 2015年 itcast. All rights reserved.
//
#import "ViewController.h"
#import "CZFriend.h"
#import "CZFriendGroup.h"
#import "CZFriendCell.h"
#import "CZFriendHeaderView.h"
@interface ViewController ()<CZFriendHeaderViewDelegate>
//所有模型数据
@property(nonatomic,strong) NSArray *friendGroups;
@end
@implementation ViewController
//懒加载
- (NSArray *)friendGroups
{
if (_friendGroups==nil) {
_friendGroups=[CZFriendGroup friendGroups];
}
return _friendGroups;
}
- (BOOL)prefersStatusBarHidden
{
return YES;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
#pragma mark UITableViewDelegate的数据源方法
//确定组的数量
- (NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return self.friendGroups.count;
}
//确定组中行的数量
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//取出组模型
CZFriendGroup *fg=self.friendGroups[section];
//返回当前组中好友数
return fg.isExpand?fg.friends.count:0;
}
//创建每一行显示的cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CZFriendCell *cell=[CZFriendCell friendCell:tableView];
//取出组模型
CZFriendGroup *fg=self.friendGroups[indexPath.section];
//取出这个组中的好友模型
CZFriend *myFriend=fg.friends[indexPath.row];
//赋值cell模型
cell.myFriend=myFriend;
return cell;
}
//titleForHeaderInSection是为每一个组指定一个头部的字符串值
//- (NSString *) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
//{
// //tableHeaderView是用来指定整个UITableView的唯一的顶部view和底部view
// self.tableView.tableHeaderView=nil;
//}
//viewForHeaderInSection是为每一个组指定一个头部的view
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
CZFriendHeaderView *hView=[CZFriendHeaderView friendHeaderView:tableView];
//指定代理
hView.delegate=self;
hView.tag=section;
//取出组模型
CZFriendGroup *fg=self.friendGroups[section];
//为头部view赋值
hView.friendGroup=fg;
return hView;
}
- (void)FriendHeaderViewButtonDidClick:(CZFriendHeaderView *)headerView
{
//reloadData会刷新数据源显示 ,会将三个数据源方法重新调用
//[self.tableView reloadData];
//我们只需要刷新当前所点击的这一组
//NSIndexSet *set=[NSIndexSet indexSetWithIndex:headerView.tag];
NSIndexSet *set=[NSIndexSet indexSetWithIndex:[self.friendGroups indexOfObject:headerView.friendGroup ]];
[self.tableView reloadSections:set withRowAnimation:UITableViewRowAnimationAutomatic];
}
@end
<pre name="code" class="objc">#import <Foundation/Foundation.h>
@interface CZFriend : NSObject
//图像
@property (nonatomic,copy) NSString *icon;
//昵称
@property (nonatomic,copy) NSString *name;
//说说
@property (nonatomic,copy) NSString *intro;
//是否vip
@property (nonatomic,assign,getter=isVip) BOOL vip;
//类方法,获取模型对象
+ (instancetype) friendWithDic:(NSDictionary *)dic;
//实例方法,获取模型对象
- (instancetype) initWithDic:(NSDictionary *)dic;
//通过字典数组,返回模型数组
+ (NSArray *)friends :(NSArray *)sourceArr;
@end
<pre name="code" class="objc">//
// CZFriend.m
// 02QQ好友列表
//
// Created by Itcast.GuangZhou on 15/9/25.
// Copyright (c) 2015年 itcast. All rights reserved.
//
#import "CZFriend.h"
@implementation CZFriend
//类方法,获取Friend模型对象
+ (instancetype) friendWithDic:(NSDictionary *)dic
{
return [[self alloc] initWithDic:dic];
}
//实例方法,获取Friend模型对象
- (instancetype) initWithDic:(NSDictionary *)dic
{
if(self=[super init])
{
[self setValuesForKeysWithDictionary:dic];
}
return self;
}
//将好友字典数组转换为好友模型数组
+ (NSArray *)friends :(NSArray *)sourceArr
{
NSMutableArray *desArr=[NSMutableArray array];
for (NSDictionary *dic in sourceArr) {
//将字典转模型
CZFriend *f=[CZFriend friendWithDic:dic];
[desArr addObject:f];
}
return desArr;
}
@end
<pre name="code" class="objc">//
// CZFriendGroup.h
// 02QQ好友列表
//
// Created by Itcast.GuangZhou on 15/9/25.
// Copyright (c) 2015年 itcast. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface CZFriendGroup : NSObject
//组名
@property (nonatomic,copy) NSString *name;
//在线人数
@property (nonatomic,assign) int online;
//该组好友数组
@property (nonatomic,strong) NSArray *friends;
//类方法,获取好友组模型数据
+ (instancetype) friendGroupWithDic:(NSDictionary *)dic;
//实例方法,获取好友组模型数据
- (instancetype) initWithDic:(NSDictionary *)dic;
//返回所有组模型数据
+ (NSArray *)friendGroups;
//标记是否展开,一开始都是合并
@property (nonatomic,assign) BOOL isExpand;
@end
<pre name="code" class="objc">//
// CZFriendGroup.m
// 02QQ好友列表
//
// Created by Itcast.GuangZhou on 15/9/25.
// Copyright (c) 2015年 itcast. All rights reserved.
//
#import "CZFriendGroup.h"
#import "CZFriend.h"
@implementation CZFriendGroup
//类方法返回组模型数据
+ (instancetype) friendGroupWithDic:(NSDictionary *)dic
{
return [[CZFriendGroup alloc] initWithDic:dic];
}
//实例方法返回组模型数据
- (instancetype) initWithDic:(NSDictionary *)dic
{
if(self=[super init])
{
[self setValuesForKeysWithDictionary:dic];
// self.friends=dic[@"friends"];
// self.name=dic[@"name"];
// self.online=dic[@"online"];
}
return self;
}
//返回好友组模型数组
+ (NSArray *)friendGroups
{
NSArray *souArr=[NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"friends.plist" ofType:nil]];
NSMutableArray *desArr=[[NSMutableArray alloc] init];
for (NSDictionary *dic in souArr) {
CZFriendGroup *group=[CZFriendGroup friendGroupWithDic:dic];
//这里面的friends是字典数组,而不是模型数组,所以需要再将字典转换为模型
group.friends=[CZFriend friends:group.friends];
[desArr addObject:group];
}
return desArr;
}
@end
<pre name="code" class="objc">//
// CZFriendCell.h
// 02QQ好友列表
//
// Created by Itcast.GuangZhou on 15/9/25.
// Copyright (c) 2015年 itcast. All rights reserved.
//
#import <UIKit/UIKit.h>
@class CZFriend;
@interface CZFriendCell : UITableViewCell
+ (instancetype) friendCell:(UITableView *)tableView;
@property (nonatomic,strong) CZFriend *myFriend;
@end
<pre name="code" class="objc">//
// CZFriendCell.m
// 02QQ好友列表
//
// Created by Itcast.GuangZhou on 15/9/25.
// Copyright (c) 2015年 itcast. All rights reserved.
//
#import "CZFriendCell.h"
#import "CZFriend.h"
@implementation CZFriendCell
//如果是结构相同,数据不同,但是系统自带的cell不能满足需要的时候,一般可以使用xib|动态单元格
//2.如果使用代码创建自定义cell,一般需要做initWithStyle方法的重写
+ (instancetype)friendCell:(UITableView *)tableView
{
NSString *ID=@"friend";
CZFriendCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
if (cell==nil) {
NSLog(@"我创建了cell");
cell=[[CZFriendCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
else
{
NSLog(@"我重用了cell");
}
return cell;
}
- (void)setMyFriend:(CZFriend *)myFriend
{
_myFriend=myFriend;
self.imageView.image=[UIImage imageNamed:myFriend.icon];
self.textLabel.text=myFriend.name;
self.detailTextLabel.text=myFriend.intro;
if (myFriend.isVip) {
self.textLabel.textColor=[UIColor redColor];
}
else
{
self.textLabel.textColor=[UIColor blackColor];
}
}
@end
<pre name="code" class="objc">//
// CZFriendHeaderView.h
// 02QQ好友列表
//
// Created by Itcast.GuangZhou on 15/9/25.
// Copyright (c) 2015年 itcast. All rights reserved.
//
#import <UIKit/UIKit.h>
@class CZFriendGroup;
@class CZFriendHeaderView;
@protocol CZFriendHeaderViewDelegate <NSObject>
@optional
- (void)FriendHeaderViewButtonDidClick:(CZFriendHeaderView *)headerView;
@end
@interface CZFriendHeaderView : UITableViewHeaderFooterView
+ (instancetype) friendHeaderView:(UITableView *) tableView;
@property (nonatomic,strong) CZFriendGroup *friendGroup;
//定义代理属性,能够遵守并实现我代理方法的就可以成为我的代理
@property (nonatomic,weak) id<CZFriendHeaderViewDelegate> delegate;
@end
<pre name="code" class="objc">//
// CZFriendHeaderView.m
// 02QQ好友列表
//
// Created by Itcast.GuangZhou on 15/9/25.
// Copyright (c) 2015年 itcast. All rights reserved.
//
#import "CZFriendHeaderView.h"
#import "CZFriendGroup.h"
@interface CZFriendHeaderView ()
@property (nonatomic,weak) UIButton *btn;
@property (nonatomic,weak) UILabel *numberLabel;
@end
@implementation CZFriendHeaderView
//返回当前自定义的每一个组的头部view
+ (instancetype)friendHeaderView:(UITableView *)tableView
{
NSString *ID=@"headerView";
CZFriendHeaderView *headerView=[tableView dequeueReusableHeaderFooterViewWithIdentifier:ID];
if (headerView==nil) {
NSLog(@"headerView 重新创建了");
//父类这个方法创建一个空的headerView,我们需要对这个方法进行重写
headerView=[[CZFriendHeaderView alloc] initWithReuseIdentifier:ID];
}
else
{
NSLog(@"headerView 重用了");
}
return headerView;
}
//在init方法里面只是添加子控件,而不去设置frame和数据
- (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
{
//NSLog(@"%@",NSStringFromCGRect(self.frame));
self=[super initWithReuseIdentifier:reuseIdentifier];
if (self) {
//添加自定义的子控件
//1.添加按钮
UIButton *btn=[[UIButton alloc] init];
//btn.frame=CGRectMake(0, 0, 375, 44);
//设置小图标
[btn setImage:[UIImage imageNamed:@"buddy_header_arrow"] forState:UIControlStateNormal];
//设置背景
[btn setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"buddy_header_bg_highlighted"] forState:UIControlStateHighlighted];
[btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
self.btn=btn;
//设置按钮内容的左对齐
btn.contentHorizontalAlignment=UIControlContentHorizontalAlignmentLeft;
//为按钮添加点击事件
[btn addTarget:self action:@selector(headerBtnDidCilck) forControlEvents:UIControlEventTouchUpInside];
//设置按钮的旋转是按默认的旋转轴心进行旋转
self.btn.imageView.contentMode=UIViewContentModeCenter;
// //设置按钮旋转后,超出原始边界的部分不要截切,要保留
self.btn.imageView.clipsToBounds=NO;
//添加创建好的按钮到头部view
[self addSubview:btn];
//2.添加UILabel
UILabel *numberLabel=[[UILabel alloc] init];
//numberLabel.frame=CGRectMake(300, 0, 75, self.frame.size.height);
//numberLabel.backgroundColor=[UIColor redColor];
//设置文本右对齐
numberLabel.textAlignment=NSTextAlignmentRight;
//设置按钮左间距
btn.contentEdgeInsets=UIEdgeInsetsMake(0, 10, 0, 0);
//设置按钮文本与小图标之间的距离
btn.titleEdgeInsets=UIEdgeInsetsMake(0, 10, 0, 0);
self.numberLabel=numberLabel;
[self addSubview:numberLabel];
}
return self;
}
- (void)setFriendGroup:(CZFriendGroup *)friendGroup
{
_friendGroup=friendGroup;
[self.btn setTitle:friendGroup.name forState:UIControlStateNormal];
self.numberLabel.text=[NSString stringWithFormat:@"%d/%ld",friendGroup.online,friendGroup.friends.count];
}
//将当前控件添加到父容器的时候调用这个方法
- (void) willMoveToSuperview:(UIView *)newSuperview
{
//重新创建headerView会调用这个Set赋值方法
if(self.friendGroup.isExpand)
{
//将小图标进行旋转
self.btn.imageView.transform=CGAffineTransformMakeRotation(M_PI_2);
}
else
{
self.btn.imageView.transform=CGAffineTransformMakeRotation(0);
}
}
//将一个控件 添加到父容器的时候,会自动调用这个方法设置它的子控件的frame
- (void)layoutSubviews
{
//NSLog(@"frame:%@",NSStringFromCGRect(self.frame));
[super layoutSubviews];
self.btn.frame=CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
self.numberLabel.frame=CGRectMake(300, 0, 65, self.frame.size.height);
}
- (void) headerBtnDidCilck
{
//修改当前 的展开属性
self.friendGroup.isExpand=!self.friendGroup.isExpand;
//当有点击操作的时候,就告诉(tell)它的代理进行处理
if ([self.delegate respondsToSelector:@selector(FriendHeaderViewButtonDidClick:)]) {
[self.delegate FriendHeaderViewButtonDidClick:self];
}
}
@end