• 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

     

  • 相关阅读:
    Windows下安装MongoDB
    介绍了MongoDB在32位Windows7下的安装以及一些简单应用
    简单的实例来理解WCF 数据服务
    对缓存的思考——提高命中率
    如何在安装过程中部署DevExpress控件
    [WCF REST] 解决资源并发修改的一个有效的手段:条件更新(Conditional Update)
    MEF实现IoC
    Lucene索引分析工具Luke.Net 0.5升级版 (兼容Lucene.Net 2.9.4.1)
    Mongodb在windows下面作为服务启动 出现“服务没有响应控制功能”
    写自己的ASP.NET MVC框架
  • 原文地址:https://www.cnblogs.com/xiaomoge/p/4200599.html
Copyright © 2020-2023  润新知