首页 > 代码库 > day01好友列表折叠效果实现

day01好友列表折叠效果实现

1.实现效果

技术分享          技术分享

2.关键点:每个分组的展开和折叠,主要是对每组的行数进行设置,展开为count,折叠为0

3.思想思路:先实现数据模型逻辑-->展示基本数据-->自定义cell-->自定义cellHeaderView视图-->在cellHeaderView中设置协议,controller中遵守协议,实现cellHeaderView点击事件的传递(即好友列表折叠点击事件的实现)

4.主要代码

1)friend ,group数据模型的定义

 1 // 2 //  FriendModel.h 3 //  1.自定义cell(纯代码) 4 // 5 //  Created by 许霞 on 16/9/7. 6 //  Copyright © 2016年 jmchat. All rights reserved. 7 // 8  9 #import <Foundation/Foundation.h>10 11 @interface FriendModel : NSObject12 /**13  *  图片14  */15 @property (nonatomic,copy) NSString *icon;16 /**17  *  介绍18  */19 @property (nonatomic,copy) NSString *intro;20 /**21  * 姓名22  */23 @property (nonatomic,copy) NSString *name;24 /**25  *  是否是vip26  */27 @property (nonatomic,assign,getter=isVip) BOOL vip;28 29 - (instancetype)initWithDict:(NSDictionary *)dict;30 + (instancetype)friendModelWithDict:(NSDictionary *)dict;31 @end
////  FriendModel.m//  1.自定义cell(纯代码)////  Created by 许霞 on 16/9/7.//  Copyright © 2016年 jmchat. All rights reserved.//#import "FriendModel.h"@implementation FriendModel- (instancetype)initWithDict:(NSDictionary *)dict{    if (self =[super init]) {        [self setValuesForKeysWithDictionary:dict];    }    return self;}+ (instancetype)friendModelWithDict:(NSDictionary *)dict{    return [[self alloc] initWithDict:dict];}@end
////  GroupModel.h//  1.自定义cell(纯代码)////  Created by 许霞 on 16/9/7.//  Copyright © 2016年 jmchat. All rights reserved.//#import <Foundation/Foundation.h>@interface GroupModel : NSObject/** *  姓名 */@property (nonatomic,copy) NSString *name;/** *  在线数 */@property (nonatomic,assign) int online;/** *  朋友 */@property (nonatomic,strong) NSArray *friends;/** *  是否展开 */@property (nonatomic,assign,getter=isOpened) BOOL opened;+ (instancetype)groupModelWithDict:(NSDictionary *)dict;- (instancetype)initWithDict:(NSDictionary *)dict;@end
////  GroupModel.m//  1.自定义cell(纯代码)////  Created by 许霞 on 16/9/7.//  Copyright © 2016年 jmchat. All rights reserved.//#import "GroupModel.h"#import "FriendModel.h"@implementation GroupModel+ (instancetype)groupModelWithDict:(NSDictionary *)dict{    return [[self alloc] initWithDict:dict];}- (instancetype)initWithDict:(NSDictionary *)dict{    if (self =[super init]) {        [self setValuesForKeysWithDictionary:dict];    }    NSMutableArray * friendArray =[NSMutableArray array];    for (NSDictionary * friendDict in _friends) {        FriendModel * friend =[FriendModel friendModelWithDict:friendDict];        [friendArray addObject:friend];    }    _friends = friendArray;    return self;}@end

2)cell,headerView的定义

////  FriendTableViewCell.h//  1.自定义cell(纯代码)////  Created by 许霞 on 16/9/7.//  Copyright © 2016年 jmchat. All rights reserved.//#import <UIKit/UIKit.h>@class FriendModel;@interface FriendTableViewCell : UITableViewCell@property (nonatomic,strong) FriendModel * friendData;+(instancetype) cellWithTableView:(UITableView *)tableView;@end
////  FriendTableViewCell.m//  1.自定义cell(纯代码)////  Created by 许霞 on 16/9/7.//  Copyright © 2016年 jmchat. All rights reserved.//#import "FriendTableViewCell.h"#import "FriendModel.h"@implementation FriendTableViewCell+(instancetype)cellWithTableView:(UITableView *)tableView{    static NSString *ID = @"friend";    FriendTableViewCell * cell =[tableView dequeueReusableCellWithIdentifier:ID];    if (cell == nil) {        cell = [[FriendTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];    }    return cell;}- (void)setFriendData:(FriendModel *)friendData{    _friendData = friendData;    self.textLabel.text =_friendData.name;    self.detailTextLabel.text = _friendData.intro;    self.imageView.image =[UIImage imageNamed:_friendData.icon];    self.textLabel.textColor = _friendData.isVip?[UIColor redColor]:[UIColor blackColor];}@end
////  GroupHeaderView.h//  1.自定义cell(纯代码)////  Created by 许霞 on 16/9/7.//  Copyright © 2016年 jmchat. All rights reserved.//#import <UIKit/UIKit.h>@class GroupModel,GroupHeaderView;@protocol  GroupHeaderViewDelegate <NSObject>@optional- (void)headerViewDidClickedNameView:(GroupHeaderView *)headerView;@end@interface GroupHeaderView : UITableViewHeaderFooterView@property (nonatomic, strong) GroupModel * group;@property (nonatomic, weak) id <GroupHeaderViewDelegate> delegate;+(instancetype)headerViewWithTableView:(UITableView *)tableView;- (void)updateHeaderView;@end
////  GroupHeaderView.m//  1.自定义cell(纯代码)////  Created by 许霞 on 16/9/7.//  Copyright © 2016年 jmchat. All rights reserved.//#import "GroupHeaderView.h"#import "GroupModel.h"@interface GroupHeaderView ()@property (nonatomic,weak) UILabel * countView;@property (nonatomic,weak) UIButton *nameView;@end@implementation GroupHeaderView+(instancetype)headerViewWithTableView:(UITableView *)tableView;{    static NSString *ID =@"groupHeader";    GroupHeaderView * header =[tableView dequeueReusableHeaderFooterViewWithIdentifier:ID];    if (header == nil) {        header =[[GroupHeaderView alloc] initWithReuseIdentifier:ID];    }    return header;}- (id) initWithReuseIdentifier:(NSString *)reuseIdentifier{    if (self =[super initWithReuseIdentifier: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.titleEdgeInsets =UIEdgeInsetsMake(0, 10, 0, 0);        nameView.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);        nameView.imageView.contentMode = UIViewContentModeCenter;        nameView.imageView.clipsToBounds = NO;        [nameView addTarget:self action:@selector(nameViewClick) forControlEvents:UIControlEventTouchUpInside];        [self.contentView addSubview:nameView];        self.nameView = nameView;                UILabel *countView =[[UILabel alloc] init];        countView.textAlignment = NSTextAlignmentRight;        countView.textColor = [UIColor grayColor];        [self.contentView addSubview:countView];        self.countView = countView;    }    return self;}- (void)layoutSubviews{    [super layoutSubviews];    self.nameView.frame = self.bounds;        CGFloat countY = 0;    CGFloat countH =self.nameView.frame.size.height;    CGFloat countW = 150;    CGFloat countX =  self.frame.size.width-10-countW;    self.countView.frame = CGRectMake(countX, countY, countW, countH);    }-(void)setGroup:(GroupModel *)group{    _group = group;    [self.nameView setTitle:group.name forState:UIControlStateNormal];    self.countView.text =[NSString stringWithFormat:@"%d/%u",group.online,group.friends.count];}- (void)nameViewClick{    self.group.opened = !self.group.opened;    if ([self.delegate respondsToSelector:@selector(headerViewDidClickedNameView:)]) {        [self.delegate headerViewDidClickedNameView:self];    }}- (void)updateHeaderView{    if (self.group.opened) {        self.nameView.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);    }else{        self.nameView.imageView.transform = CGAffineTransformMakeRotation(0);    }    }//- (void)willMoveToSuperview:(UIView *)newSuperview//{//    if (self.group.opened) {//        self.nameView.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);//    }else{//        self.nameView.imageView.transform = CGAffineTransformMakeRotation(0);//    }//}@end

 

3)controller的实现

  1 //  2 //  ViewController.m  4 //  5 //  Created by 许霞 on 16/9/7.  6 //  Copyright © 2016年 jmchat. All rights reserved.  7 //  8   9 #import "ViewController.h" 10 #import "GroupModel.h" 11 #import "FriendModel.h" 12 #import "FriendTableViewCell.h" 13 #import "GroupHeaderView.h" 14  15 @interface ViewController ()<UITableViewDataSource,UITableViewDelegate,GroupHeaderViewDelegate> 16 @property (nonatomic,strong) UITableView * tableView; 17 @property (nonatomic,strong) NSArray * dataArray; 18 @end 19  20 @implementation ViewController 21  22 - (void)viewDidLoad { 23     [super viewDidLoad]; 24     [self initUI]; 25 } 26 /** 27  *  懒加载实现数据的加载 28  */ 29  30 - (NSArray *)dataArray 31 { 32     if (_dataArray ==nil) { 33         NSArray * dictArray =[[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"friends.plist" ofType:nil] ]; 34         NSMutableArray *groups =[NSMutableArray array]; 35         for (NSDictionary * groupDict in dictArray) { 36             GroupModel * group =[GroupModel groupModelWithDict:groupDict]; 37             [groups addObject:group]; 38         } 39         _dataArray = groups; 40     } 41     return _dataArray; 42 } 43  44 - (void) initUI 45 { 46     self.tableView.autoresizesSubviews = NO; 47     self.tableView =[[UITableView alloc] initWithFrame:CGRectMake(0, 20, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) style:UITableViewStylePlain]; 48     _tableView.delegate =self; 49     _tableView.dataSource =self; 50     _tableView.rowHeight = 50.0f; 51     _tableView.sectionHeaderHeight = 44.0f; 52     [self.view addSubview:_tableView]; 53 } 54 #pragma  mark- 55 #pragma  mark-UITableViewDataSource 56 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 57 { 58     return self.dataArray.count; 59 } 60 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 61 { 62     GroupModel * group = self.dataArray[section]; 63     return group.opened? group.friends.count:0; 64 } 65  66 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 67 { 68     //1.创建cell 69     FriendTableViewCell * cell =[FriendTableViewCell cellWithTableView:tableView]; 70     //2.设置cell数据 71     GroupModel * group =self.dataArray[indexPath.section]; 72     FriendModel * friendData =http://www.mamicode.com/ group.friends[indexPath.row]; 73     cell.friendData =http://www.mamicode.com/ friendData; 74      75      76     return cell; 77 } 78  79 - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 80 { 81     return 30.0f; 82 } 83  84 - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 85 { 86     //1.创建头部控件 87     GroupHeaderView * headerView =[GroupHeaderView headerViewWithTableView:tableView]; 88     headerView.delegate =self; 89     //2.给Header设置数据(传递模型给header) 90     headerView.group =self.dataArray[section]; 91     [headerView updateHeaderView]; 92      93     return headerView; 94 } 95  96 #pragma mark- 97 #pragma  mark --GroupHeaderViewDelegate 98 - (void)headerViewDidClickedNameView:(GroupHeaderView *)headerView 99 {100     [self.tableView reloadData];101 }102 103 104 @end

5.经验总结

1)隐藏显示状态栏方法

-(BOOL)prefersStatusBarHidden

{

    return YES;

}

2)friend 是c++关键字,不能用friend作为属性名

3)当一个控件被添加到父控件的中就会调用

- (void)didMoveToSuperView

{

}

4)headerView和cell一样,都有一个复用机制,但是当刷新tableVIew的时候,是不会从缓存池中取的,而是重新创建

5)layoutSubviews (一般在这里布局内部的子控件,设置子控件的frame,当一个控件的frame发生改变的时候就会调用)

6)tableView 的类型如果是plain可以实现组头固定显示;如果是group则无此效果,且如果为plain类型, 设置其组头,组为的高度为0有效,而group类型则无效,但可以设置为0.000001等极小数,可以实现组头,组尾视图的高度设置;

7)将数据源数组设置为不可变,是保证数据安全,不会被合作程序员不小心修改,也是让合作者透露,此数据源数组,不能更改

8)懒加载是写在get方法,如果你需要的时候,才会创建,而if(_group==nil),这里一定不能使用self.group,这样会导致循环调用

9)当模型中又包含有其他模型时,我们需要对其模型部分进行处理,大致思路仍是:用kvc实现复制,但是包含模型部分的数据,被kvc设置为了普通数据,我们单独对此部分进行重新设置即可,关键代码如下:

-(instancetype)initWithDict:(NSDictionary *)dict{ if (self =[super init]){//1.注入所有属性[self setValuesForKeysWithDictionary:dict];//2.特殊处理friends属性NSMutabelArray *friendArray =[NSMutableArray array];for (NSDictionary *dict in self.friends){ Friend * friend =[Friend friendWithDict:dict]; [friendArray addObject:friend];}self.friends = friendArray;}return self;}

10)代码仓库不确定的<#type#>进行设置

11)BOOL值属性,我们一般通过,getter关键字对其重命名

@property (nonatomic,assign,getter = isVip) BOOL vip

12)如果某个控件不出来,可以考虑的原因如下:

1.frame的尺寸和位置对不对; 2.hidden是否为YES; 3.有没有添加到父控件中; 4.alpha 是否 < 0.01; 5.被其他控件挡住了 ;6.父控件的前面5个情况.

13)按钮的一些属性:

1.设置按钮的内容的对齐方式:(垂直方向上:上下对齐;水平方向上:左右对齐)

nameView.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;

2.设置按钮的图片,文字,整体内容的内边距(这里内边距对象格式为:上左下右,逆时针方向设置)

 nameView.titleEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);

 nameView.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 0);

3.设置按钮的内容,文字,图片的显示模式

 nameView.imageView.contentMode = UIViewContentModeCenter;

4.设置按钮图片超过边框的内容是否裁剪

 nameView.imageView.clipsToBounds = NO;

 

day01好友列表折叠效果实现