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 : NSObject
12 /**
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  *  是否是vip
26  */
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 = group.friends[indexPath.row];
 73     cell.friendData = 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;

时间: 2024-08-29 07:04:48

day01好友列表折叠效果实现的相关文章

基于Qt的类似QQ好友列表抽屉效果的实现

前段时间在忙毕业设计,所以一直没有更新博客.今天答辩完以后,将对我的毕业设计进行模块展示,供Qt初学者进行参考. 毕业设计题目:Linux系统下基于Qt的局域网即时通信系统设计与实现 其中我有一个类似于QQ的好友列表,然后对好友可以进行分组管理,毕设中具体效果图如下: 网上查寻到的设计思路: 1.采用QToolBox的方式,虽然看起来有点样子,但是并不是我们所熟悉的好友列表,比如:http://blog.csdn.net/qianguozheng/article/details/6719074

鼠标事件和表单事件+好友列表选中效果+侧面菜单下拉效果

通用:onclick 鼠标单击ondblclick 鼠标双击onmouseover 鼠标放上onmouseout 鼠标离开onmousemove 鼠标移动 表单:onchang 表单的值改变onblur 失去焦点onfocus 获得焦点onselect 选中 2.好友列表选中效果 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/

Js效果:图片轮播;选项卡;侧面菜单下拉效果;进度条效果;滑动效果;好友列表选中效果;点击选中显示效果

选项卡效果表: <body><div id="aaa"> <div class="bbb" style="width:50px; height:30px; background-color:#3F0" onclick="Show('d1')">娱乐</div> <div class="bbb" style="width:50px; height

树形 列表折叠效果

代码: <!DOCTYPE HTML> <html> <head> <title>读取并修改元素的内容</title> <meta charset="utf-8" /> <style> div{float:left; height: 100px; line-height: 100px; } #d1,#d3{ background-color: #ccff00; } #d2{ cursor: pointe

JS实例之列表选中,实现类似好友列表选中效果

1 <head> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 3 <title>无标题文档</title> 4 <style type="text/css"> 5 *{margin:0px auto; padding:0px;} 6 #wai{width:100px; height:110

例子:好友列表选中效果

<style type="text/css"> *{ margin:0px auto; padding:0px; font-family:微软雅黑; font-size:16px;} .f{ width:200px; height:30px; background-color:#63C; color:white; text-align:center; line-height:30px; vertical-align:middle; margin-top:3px} .f:ho

WPF—QQ界面(五):QQ好友分组列表的效果实现 及 截稿

效果分析: 1.鼠标左键单击 分组 的组名,能够弹出一个下拉列表,并且左边的向右箭头转成向下: 2.弹出的下拉列表中包含好友的头像,好友的昵称,还有好友的个性签名或最新动态: 3.当鼠标移到好友这一行,能够将一行的背景色置蓝或置橙: 4.当鼠标移到好友的头像上,能够悬浮显示好友的个人信息. 除了这些基本的效果,还有很多效果蕴含其中....感觉分组列表的效果最难做. 我大致做出了那样的效果,很不美观.没达到一样的效果,就不分析思路了,以免误人子弟. 用的是ScrollViewer 前台: <Scr

JavaScript实现的购物车效果-好友列表效果

JavaScript实现的购物车效果,当然这个效果可以运用在好多地方,比如好友的选择,人力资源模块,计算薪资,人员的选择等等.下面看类似某种购物车的效果图: code: goodsCar.js:这个js写成了一个单独的文件.主要是控制上面的列表显示的. window.onload=function(){ initStore(); }; var goods=["火腿","美女","御姐","火星一日游","跑车&quo

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

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